I'm trying to use an Incrementable type with a boost::counting_iterator
.
The boost::counting_iterator
documentation says that the iterator works for Incrementable types, i.e. types that are CopyConstructible, Assignable, PreIncrementable, and EqualityComparable.
My Incrementable type:
template<class T> struct Incrementable {
// CopyConstructible:
Incrementable() : value(0) {}
Incrementable(const Incrementable& other) : value(other.value) {}
explicit Incrementable(const T& other) : value(other) {}
// Assignable:
inline Incrementable& operator=(const Incrementable& other) {
value = other.value;
return *this;
}
// PreIncrementable:
inline Incrementable& operator++() {
++value;
return *this;
}
// EqualityComparable:
friend
inline bool operator==(const Incrementable& a, const Incrementable& b) {
return a.value == b.value;
}
T value;
};
This fails to compile:
#include <boost/iterator/counting_iterator.hpp>
#include "incrementable.h"
int main() {
boost::counting_iterator<Incrementable<int>> a(Incrementable<int>(0));
return 0;
}
The error:
usr/local/include/boost/iterator/iterator_categories.hpp:161:60: error: no type named 'iterator_category' in 'boost::detail::iterator_traits<Incrementable<int> >'
typename boost::detail::iterator_traits<Iterator>::iterator_category
I'd guess that I need to implement an iterator_category either for:
- a counting_iterator of my Incrementable type,
- or as the error says, for my Incrementable type (does this even make sense? my Incrementable type is not an iterator).
Neither is clear from the documentation (which omits this topic completely), and I fail to find any information about it in the other parts of the library.
So I added the following to boost::detail
namespace:
namespace boost { namespace detail {
template <class T> struct is_numeric<Incrementable<T>>
: mpl::true_ {};
}} // boost::detail namespace
and now everything compiles and works as expected. Still, I really doubt that the library was intended to be used this way.
Anyone knows the proper/clean way to implement this?
Steve Jessop's suggestion: specializing std::numeric_limits
also works:
namespace std {
template<class T>
class numeric_limits<Incrementable<T>> : public numeric_limits<T> {
public:
static const bool is_specialized = true;
};
}
Still I don't know if this is the right thing to do for an incrementable type.