1 #pragma once
2 
3 #include <iterator>
4 
5 template <typename I>
6 class null_sentinel_iterator
7 {
8 public:
9 	using iterator_category = std::forward_iterator_tag;
10 	using value_type = I;
11 	using difference_type = std::ptrdiff_t;
12 	using pointer = I *;
13 	using reference = I &;
14 	null_sentinel_iterator() = default;
null_sentinel_iterator(const pointer i)15 	null_sentinel_iterator(const pointer i) :
16 		p(i)
17 	{
18 	}
get()19 	pointer get() const
20 	{
21 		return p;
22 	}
23 	value_type operator*() const
24 	{
25 		return *p;
26 	}
27 	reference operator*()
28 	{
29 		return *p;
30 	}
31 	null_sentinel_iterator &operator++()
32 	{
33 		++p;
34 		return *this;
35 	}
36 	bool operator==(null_sentinel_iterator rhs) const
37 	{
38 		if (rhs.p)
39 			return p == rhs.p;
40 		if (!p)
41 			/* Should never happen */
42 			return true;
43 		return !**this;
44 	}
45 	bool operator!=(null_sentinel_iterator rhs) const
46 	{
47 		return !(*this == rhs);
48 	}
49 private:
50 	pointer p = nullptr;
51 };
52 
53 template <typename I>
54 class null_sentinel_array
55 {
56 	typedef null_sentinel_iterator<I> iterator;
57 	I *b;
58 public:
null_sentinel_array(I * i)59 	null_sentinel_array(I *i) :
60 		b(i)
61 	{
62 	}
begin()63 	iterator begin() const
64 	{
65 		return b;
66 	}
end()67 	iterator end() const
68 	{
69 		return {};
70 	}
71 };
72 
73 template <typename I>
make_null_sentinel_array(I * i)74 static inline null_sentinel_array<I> make_null_sentinel_array(I *i)
75 {
76 	return i;
77 }
78