Skip to content

Latest commit

 

History

History
154 lines (120 loc) · 3.14 KB

sentinels.md

File metadata and controls

154 lines (120 loc) · 3.14 KB

What is a sentinel?

Value Type
  • Special value, same type.
  • Indicates end of a range.
  • Most famous: ‘\0’
  • "New" to std::ranges.
  • Class returned by end() calls.
  • Checks == with iterator type.

Sentinel semantic requirements:

Let s and i be values of type S and I, respectively, such that [i, s) 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 [++i, s) denotes a range.
  • std::assignable_from<I&, S> is either modeled or not satisfied.

template <class S, class I>
concept sentinel_for =
	std::semiregular<S> &&
	std::input_or_output_iterator<I> &&
	__WeaklyEqualityComparableWith<S, I>;
class inner_sentinel
{
public:
	[[nodiscard]] bool operator==(inner_sentinel const&) const
	{
		return true;
	}
 
	[[nodiscard]] bool operator==(inner_iterator const& rhs) const
	{
		return rhs._current_inner == std::ranges::end(*rhs._base);
	}

    /* As of C++20, the compiler uses this^ to generate these:
     *    sentinel != iterator
     *    iterator == sentinel
     *    iterator != sentinel
     */
};

Why use a sentinel instead
of an end iterator?

class inner_iterator
{
    /* ... */
    inner_iterator(TBase const& base, base_iterator current_outer)
		: _current_outer{ std::move(current_outer) }
		, _current_inner{ std::ranges::begin(base) }
		, _base{ std::addressof(base) }
	{
		correct_inner_if_needed();
	}
    /* ... */
};
class inner_iterator
{
    /* ... */
    inner_iterator(TBase const& base, base_iterator current_outer, 
                   base_iterator current_inner)
		: _current_outer{ std::move(current_outer) }
		, _current_inner{ std::move(current_inner) }
		, _base{ std::addressof(base) }
	{
		correct_inner_if_needed(); // Should I even do this..?
	}
    /* ... */
};

This constructor is only for end() to use,
but nothing actually tells us that.

Sentinels separate concerns.

The definition of "end" is in its own class.