Skip to main content
Code Review

Return to Question

added 215 characters in body
Source Link
JDługosz
  • 11.7k
  • 19
  • 40

It is mostly boilerplate, going through the list of requirements for different iterator types and making sure all the functions are there to be a bidirectional(削除) bidirectional (削除ここまで) random-access iterator. That is why all the functions have explicit return types declared even though they are trivial — to make sure it matches what the docs state.

It is mostly boilerplate, going through the list of requirements for different iterator types and making sure all the functions are there to be a bidirectional iterator. That is why all the functions have explicit return types declared even though they are trivial — to make sure it matches what the docs state.

It is mostly boilerplate, going through the list of requirements for different iterator types and making sure all the functions are there to be a (削除) bidirectional (削除ここまで) random-access iterator. That is why all the functions have explicit return types declared even though they are trivial — to make sure it matches what the docs state.

added 215 characters in body
Source Link
JDługosz
  • 11.7k
  • 19
  • 40

An intro to this is on Code Project: DIY μ-range , and the complete code is in GuiHub .



An intro to this is on Code Project: DIY μ-range , and the complete code is in GuiHub .


Source Link
JDługosz
  • 11.7k
  • 19
  • 40

Acts like an iterator, but counts

I’m making a "counting iterator" which emulates a constant container of consecutive values of some integral type.

It is mostly boilerplate, going through the list of requirements for different iterator types and making sure all the functions are there to be a bidirectional iterator. That is why all the functions have explicit return types declared even though they are trivial — to make sure it matches what the docs state.

Everything is noexcept because they are only simple integer operations. If someone instantiates it with a bignum class, that will not necessarily be right, but I don’t expect that at a use case. I’ll just document it as not supporting exceptions in the simple arithmetic primitives, and IAC never tested for weird classes.

This library is supposed to be simple and fairly minimal for a set of common use cases. It is meant to help people understand the magic before understanding the fullness of Range.v3, and show how things are done without a lot of metaprogramming or huge infrastructure behind the class.

count_iter.h

#include <type_traits>
#include <iterator>
namespace Dlugosz::d3 {
inline namespace minirange {
template <typename T = int>
struct count_iter {
 T value;
 using difference_type = std::make_signed_t<T>;
 explicit count_iter (T value) noexcept : value{value}
 {
 static_assert (std::is_integral_v<T>, "count_iter is meant for integer-like types");
 }
 T operator* () const noexcept { return value; }
 T& operator* () noexcept { return value; }
 // no operator-> because T has no members!
 count_iter& operator++ () noexcept { ++value; return *this; }
 count_iter operator++ (int) noexcept { auto temp= *this; ++value; return temp; }
 count_iter& operator+= (difference_type n) noexcept { value+=n; return *this; }
 count_iter& operator-- () noexcept { --value; return *this; }
 count_iter operator-- (int) { auto temp= *this; --value; return temp; }
 count_iter& operator-= (difference_type n) { value-=n; return *this; }
};
template <typename T>
bool operator== (const count_iter<T>& left, const count_iter<T>& right) noexcept
{
 return left.value == right.value;
}
template <typename T>
bool operator!= (const count_iter<T>& left, const count_iter<T>& right) noexcept
{
 return !(left==right);
}
template <typename T>
count_iter<T> operator+ (count_iter<T> left, typename count_iter<T>::difference_type right) noexcept
{
 left += right;
 return left;
}
template <typename T>
count_iter<T> operator+ (typename count_iter<T>::difference_type left, count_iter<T> right) noexcept
{
 right += left;
 return right;
}
template <typename T>
count_iter<T> operator- (count_iter<T> left, typename count_iter<T>::difference_type right) noexcept
{
 left -= right;
 return left;
}
template <typename T>
typename count_iter<T>::difference_type
operator- (count_iter<T> left, count_iter<T> right) noexcept
{
 return right.value - left.value;
}
template <typename T>
bool operator< (count_iter<T> left, count_iter<T> right) noexcept
{
 return left.value < right.value;
}
template <typename T>
bool operator> (count_iter<T> left, count_iter<T> right) noexcept
{
 return left.value > right.value;
}
template <typename T>
bool operator<= (count_iter<T> left, count_iter<T> right) noexcept
{
 return left.value <= right.value;
}
template <typename T>
bool operator>= (count_iter<T> left, count_iter<T> right) noexcept
{
 return left.value >= right.value;
}
}}
template <typename T>
struct std::iterator_traits<Dlugosz::d3::count_iter<T>> {
 using difference_type = typename Dlugosz::d3::count_iter<T>::difference_type;
 using value_type = T;
 using pointer = T;
 using reference = T&;
 using iterator_category = std::bidirectional_iterator_tag;
};

some usage code

void f() {
 count_iter B {1};
 count_iter E {42};
 for (auto it=B; it != E; ++it)
 cout << ' ' << *it;
 cout << '\n';
}
void g() {
 range_view<count_iter<>> counter {count_iter{1},count_iter{42}};
 for (auto i : counter)
 cout << ' ' << i;
 cout << '\n';
 int total = std::accumulate (counter.begin(), counter.end(), 0);
 cout << "total accumulated is: " << total << '\n';
 auto found = std::find (counter.begin(), counter.end(), 18);
 cout << "found 18? " << *found << '\n';
 bool found2 = std::binary_search (counter.begin(), counter.end(), 18);
 cout << "binary search? " << found2 << '\n';
}
lang-cpp

AltStyle によって変換されたページ (->オリジナル) /