Title
common_iterator should be completely constexpr-able
Status
c++23
Section
[common.iterator]
Submitter
Hewill Kang

Created on 2021-07-21.00:00:00 last changed 13 months ago

Messages

Date: 2021-10-14.09:56:08

Proposed resolution:

This wording is relative to N4892.

  1. Modify [common.iterator], class template common_iterator synopsis, as indicated:

    namespace std {
      template<input_or_output_iterator I, sentinel_for<I> S>
        requires (!same_as<I, S> && copyable<I>)
      class common_iterator {
      public:
        constexpr common_iterator() requires default_initializable<I> = default;
        constexpr common_iterator(I i);
        constexpr common_iterator(S s);
        template<class I2, class S2>
          requires convertible_to<const I2&, I> && convertible_to<const S2&, S>
            constexpr common_iterator(const common_iterator<I2, S2>& x);
            
        template<class I2, class S2>
          requires convertible_to<const I2&, I> && convertible_to<const S2&, S> &&
                   assignable_from<I&, const I2&> && assignable_from<S&, const S2&>
          constexpr common_iterator& operator=(const common_iterator<I2, S2>& x);
    
        constexpr decltype(auto) operator*();
        constexpr decltype(auto) operator*() const
          requires dereferenceable<const I>;
        constexpr decltype(auto) operator->() const
          requires see below;
     
        constexpr common_iterator& operator++();
        constexpr decltype(auto) operator++(int);
    
        template<class I2, sentinel_for<I> S2>
          requires sentinel_for<S, I2>
        friend constexpr bool operator==(
          const common_iterator& x, const common_iterator<I2, S2>& y);
        template<class I2, sentinel_for<I> S2>
          requires sentinel_for<S, I2> && equality_comparable_with<I, I2>
        friend constexpr bool operator==(
          const common_iterator& x, const common_iterator<I2, S2>& y);
    
        template<sized_sentinel_for<I> I2, sized_sentinel_for<I> S2>
          requires sized_sentinel_for<S, I2>
        friend constexpr iter_difference_t<I2> operator-(
          const common_iterator& x, const common_iterator<I2, S2>& y);
    
        friend constexpr iter_rvalue_reference_t<I> iter_move(const common_iterator& i)
          noexcept(noexcept(ranges::iter_move(declval<const I&>())))
            requires input_iterator<I>;
        template<indirectly_swappable<I> I2, class S2>
          friend constexpr void iter_swap(const common_iterator& x, const common_iterator<I2, S2>& y)
            noexcept(noexcept(ranges::iter_swap(declval<const I&>(), declval<const I2&>())));
    
      private:
        variant<I, S> v_; // exposition only
      };
      […]
    }
    
  2. Modify [common.iter.const] as indicated:

    template<class I2, class S2>
      requires convertible_to<const I2&, I> && convertible_to<const S2&, S> &&
               assignable_from<I&, const I2&> && assignable_from<S&, const S2&>
        constexpr common_iterator& operator=(const common_iterator<I2, S2>& x);
    

    -5- Preconditions: x.v_.valueless_by_exception() is false.

    […]

  3. Modify [common.iter.access] as indicated:

    constexpr decltype(auto) operator*();
    constexpr decltype(auto) operator*() const
      requires dereferenceable<const I>;
    

    -1- Preconditions: holds_alternative<I>(v_) is true.

    […]

    constexpr decltype(auto) operator->() const
      requires see below;
    

    -3- The expression in the requires-clause is equivalent to:

    […]

  4. Modify [common.iter.nav] as indicated:

    constexpr common_iterator& operator++();
    

    -1- Preconditions: holds_alternative<I>(v_) is true.

    […]

    constexpr decltype(auto) operator++(int);
    

    -4- Preconditions: holds_alternative<I>(v_) is true.

    […]

  5. Modify [common.iter.cmp] as indicated:

    template<class I2, sentinel_for<I> S2>
      requires sentinel_for<S, I2>
    friend constexpr bool operator==(
      const common_iterator& x, const common_iterator<I2, S2>& y);
    

    -1- Preconditions: […]

    template<class I2, sentinel_for<I> S2>
      requires sentinel_for<S, I2> && equality_comparable_with<I, I2>
    friend constexpr bool operator==(
      const common_iterator& x, const common_iterator<I2, S2>& y);
    

    -3- Preconditions: […]

    template<sized_sentinel_for<I> I2, sized_sentinel_for<I> S2>
      requires sized_sentinel_for<S, I2>
    friend constexpr iter_difference_t<I2> operator-(
      const common_iterator& x, const common_iterator<I2, S2>& y);
    

    -5- Preconditions: […]

  6. Modify [common.iter.cust] as indicated:

    friend constexpr iter_rvalue_reference_t<I> iter_move(const common_iterator& i)
      noexcept(noexcept(ranges::iter_move(declval<const I&>())))
        requires input_iterator<I>;
    

    -1- Preconditions: […]

    template<indirectly_swappable<I> I2, class S2>
      friend constexpr void iter_swap(const common_iterator& x, const common_iterator<I2, S2>& y)
        noexcept(noexcept(ranges::iter_swap(declval<const I&>(), declval<const I2&>())));
    

    -3- Preconditions: […]

Date: 2021-10-14.00:00:00

[ 2021-10-14 Approved at October 2021 virtual plenary. Status changed: Voting → WP. ]

Date: 2021-08-15.00:00:00

[ 2021-08-23; Reflector poll ]

Set status to Tentatively Ready after five votes in favour during reflector poll.

Date: 2021-08-15.00:00:00

[ 2021-08-20; Reflector poll ]

Set priority to 3 after reflector poll.

Date: 2021-07-21.00:00:00

After P2231R1, variant becomes completely constexpr-able, which means that common_iterator can also be completely constexpr-able.

History
Date User Action Args
2023-11-22 15:47:43adminsetstatus: wp -> c++23
2021-10-14 09:56:08adminsetmessages: + msg12136
2021-10-14 09:56:08adminsetstatus: voting -> wp
2021-09-29 12:57:28adminsetstatus: ready -> voting
2021-08-23 07:45:47adminsetmessages: + msg12015
2021-08-23 07:45:47adminsetstatus: new -> ready
2021-08-20 17:17:04adminsetmessages: + msg12005
2021-07-25 17:07:36adminsetmessages: + msg11975
2021-07-21 00:00:00admincreate