Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/iterator/sentinel for"

From cppreference.com
< cpp‎ | iterator
(LWG 3453)
(Semantic requirements: link to cpp/iterator#Ranges)
 
(2 intermediate revisions by 2 users not shown)
Line 2: Line 2:
 
{{cpp/iterator/navbar}}
 
{{cpp/iterator/navbar}}
 
{{ddcl|header=iterator|since=c++20|1=
 
{{ddcl|header=iterator|since=c++20|1=
template<class S, class I>
+
template< class S, class I >
  concept sentinel_for =
+
    concept sentinel_for =
    std::semiregular<S> &&
+
        std::semiregular<S> &&
    std::input_or_output_iterator<I> &&
+
        std::input_or_output_iterator<I> &&
    __WeaklyEqualityComparableWith<S, I>;
+
        __WeaklyEqualityComparableWith<S, I>;
 
}}
 
}}
  
Line 12: Line 12:
  
 
===Semantic requirements===
 
===Semantic requirements===
Let {{tt|s}} and {{tt|i}} be values of type {{tt|S}} and {{tt|I}}, respectively, such that {{tt|[i, s)}} denotes a range. {{tt|sentinel_for&lt;S, I>}} is modeled only if:
+
Let {{tt|s}} and {{tt|i}} be values of type {{tt|S}} and {{tt|I}}, respectively, such that {{range|i|s}} denotes a [[cpp/iterator#Ranges|range]]. {{tt|sentinel_for&lt;S, I>}} is modeled only if:
  
 
* {{c|1=i == s}} is well-defined.
 
* {{c|1=i == s}} is well-defined.
* If {{c|1=bool(i != s)}} then {{tt|i}} is dereferenceable and {{tt|[++i, s)}} denotes a range.
+
* If {{c|1=bool(i != s)}} then {{tt|i}} is dereferenceable and {{range|++i|s}} denotes a range.
 
* {{c|std::assignable_from<I&, S>}} is either modeled or not satisfied.
 
* {{c|std::assignable_from<I&, S>}} is either modeled or not satisfied.
  
The domain of {{tt|1===}} can change over time. Given an iterator {{tt|i}} and sentinel {{tt|s}} such that {{tt|[i, s)}} denotes a range and {{c|1=i != s}}, {{tt|[i, s)}} is not required to continue to denote a range after incrementing any iterator equal to {{tt|i}} (and so {{c|1=i == s}} is no longer required to be well-defined after such an increment).
+
The domain of {{tt|1===}} can change over time. Given an iterator {{tt|i}} and sentinel {{tt|s}} such that {{range|i|s}} denotes a range and {{c|1=i != s}}, {{range|i|s}} is not required to continue to denote a range after incrementing any iterator equal to {{tt|i}} (and so {{c|1=i == s}} is no longer required to be well-defined after such an increment).
  
 
===Notes===
 
===Notes===
A sentinel type and its corresponding iterator type are not required to model {{lconcept|equality_comparable_with}}, because the sentinel type may be not comparable with itself, and they are not required to have a common reference type.
+
A sentinel type and its corresponding iterator type are not required to model {{lconcept|equality_comparable_with}}, because the sentinel type may not be comparable with itself, and they are not required to have a common reference type.
  
 
It has been permitted to use a sentinel type different from the iterator type in the [[cpp/language/range-for|range-based {{tt|for}} loop]] since C++17.
 
It has been permitted to use a sentinel type different from the iterator type in the [[cpp/language/range-for|range-based {{tt|for}} loop]] since C++17.

Latest revision as of 05:23, 12 May 2024

 
 
Iterator library
Iterator concepts
sentinel_for
(C++20)

Iterator primitives
Algorithm concepts and utilities
Indirect callable concepts
Common algorithm requirements
(C++20)
(C++20)
(C++20)
Utilities
(C++20)
Iterator adaptors
Range access
(C++11)(C++14)
(C++14)(C++14)  
(C++11)(C++14)
(C++14)(C++14)  
(C++17)(C++20)
(C++17)
(C++17)
 
Defined in header <iterator>
template< class S, class I >

    concept sentinel_for =
        std::semiregular<S> &&
        std::input_or_output_iterator<I> &&

        __WeaklyEqualityComparableWith<S, I>;
(since C++20)

The sentinel_for concept specifies the relationship between an input_or_output_iterator type and a semiregular type whose values denote a range. The exposition-only concept __WeaklyEqualityComparableWith is described in equality_comparable.

[edit] Semantic requirements

Let s and i be values of type S and I, respectively, such that [is) denotes a range. sentinel_for<S, I> is modeled only if:

  • i == s is well-defined.
  • If bool(i != s) then i is dereferenceable and [++is) denotes a range.
  • std::assignable_from<I&, S> is either modeled or not satisfied.

The domain of == can change over time. Given an iterator i and sentinel s such that [is) denotes a range and i != s, [is) is not required to continue to denote a range after incrementing any iterator equal to i (and so i == s is no longer required to be well-defined after such an increment).

[edit] Notes

A sentinel type and its corresponding iterator type are not required to model equality_comparable_with, because the sentinel type may not be comparable with itself, and they are not required to have a common reference type.

It has been permitted to use a sentinel type different from the iterator type in the range-based for loop since C++17.

[edit] Defect reports

The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

DR Applied to Behavior as published Correct behavior
LWG 3453 C++20 semantic requirements for sentinel_for were too loose for ranges::advance strengthened