c++ - Custom is_sorted function template -
i want write own is_sorted function template implementation instead of using std::is_sorted. give me idea how it? want use arrays. want make declaration this:
template <typename t, size_t n> bool is_sorted (const t (&array)[n]); , bool operator>(const &, const &); declared.
the obvious way compare each item 1 after it, , see if it's <= one.
you don't want directly though. first of all, sorting, client typically required ensure a < b
defined, want use <
instead of <=
. second, want allow (but not require) user pass comparator of own, in case <
isn't defined directly type or desired sort uses different criteria <
defines.
as such, want define 2 versions of is_sorted
, 1 using <
directly, other using comparator passed user.
#include <iterator> #include <functional> template <class init> bool is_sorted(init b, init e) { if (b == e) // no items -- sorted definition return true; typename std::iterator_traits<init>::value_type first = *b; ++b; while (b != e) { // skip if e-b == 1 (single item sorted) if (*b < first) return false; first = *b; ++b; } return true; } template <class init, class cmp> bool is_sorted(init b, init e, cmp cmp) { if (b == e) return true; typename std::iterator_traits<init>::value_type first = *b; ++b; while (b != e) { // skip if e-b == 1 (single item sorte) if (cmp(*b, first)) return false; first = *b; ++b; } return true; }
to keep myself honest, bit of test code, sorted, unsorted, identical, , reversed elements, using std::vector
, std::deque
, std::array
, , built-in array:
#ifdef test #include <array> #include <vector> #include <iostream> #include <deque> int main() { std::vector<int> sorted{1, 2, 3, 4, 6, 100}; std::deque<int> unsorted{1, 5, 2, 7, 4}; std::array<int, 7> ident = {1, 1, 1, 1, 1, 3, 3}; int rev[] = {5, 4, 3, 2, 1}; if (!is_sorted(std::begin(sorted), std::end(sorted))) std::cout << "sorted array detected un-sorted\n"; if (is_sorted(std::begin(unsorted), std::end(unsorted))) std::cout << "un-sorted array detected sorted\n"; if (!is_sorted(std::begin(ident), std::end(ident))) std::cout << "sorted array duplicated detected un-sorted\n"; if (!is_sorted(std::begin(rev), std::end(rev), std::greater<int>())) std::cout << "reverse sorted array detected un-sorted\n"; return 0; } #endif
this works fine me gcc 4.7.2. is_sorted
code seems work fine vc++ 2012 (though test code requires minor modifications, e.g., eliminate use of uniform initialization, doesn't support yet).
edit: if don't mind tighter requirement on iterators (forward iterators instead of input iterators), can make code simpler , more efficient. example, code can reduced this:
template <class fwdit> bool is_sorted(fwdit b, fwdit e) { if (b == e) // no items -- sorted definition return true; (fwdit first = b; ++b != e; first = b) if (*b < *first) return false; return true; }
Comments
Post a Comment