
template<class T> bool is_singular_or_empty(const T& t) { return(t.empty()); }
template<class T> bool is_singular_or_empty(const iterator_range<T>& t) { return(t.is_singular() || t._empty()); }
Hey Steven, That was my initial approach, too.
From a library designer point of view, the reason why I was reluctant about the above is that it breaks the range contract (begin, end, empty,...) and forces my users to be aware of the idiosyncrasies of a particular range implementation.
From an implementation point of view, unfortunately, you seem to have got caught out by the same problem as me - is_singular() is only useful in debug builds. It always returns false in release builds and hence the above won't work. Worse, it will break silently, as t.empty() will end up comparing invalid iterators in release. I am sure you can see how this would be very hard to find and debug. This also illustrates my other big issue with having functions which work differently in different builds.
Kind regards, Tom