From e5aae1bb97d5f73703287358f841c6d957101dfd Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sun, 19 Jul 2015 12:06:57 +0200 Subject: Implement path iterator decrement operator --- butl/path | 25 +++++++++++++++++++++++-- tests/path/driver.cxx | 39 +++++++++++++++++++++++++++++++++++---- 2 files changed, 58 insertions(+), 6 deletions(-) diff --git a/butl/path b/butl/path index db77563..c667378 100644 --- a/butl/path +++ b/butl/path @@ -388,9 +388,9 @@ namespace butl { typedef string_type value_type; typedef string_type* pointer; - typedef string_type& reference; + typedef string_type reference; typedef std::ptrdiff_t difference_type; - typedef std::forward_iterator_tag iterator_category; + typedef std::bidirectional_iterator_tag iterator_category; typedef typename string_type::size_type size_type; @@ -409,9 +409,30 @@ namespace butl return *this; } + iterator& + operator-- () + { + e_ = b_; + + if (e_ != 0) + { + b_ = e_ == string_type::npos ? + traits::rfind_separator (*p_) /* Rigtmost component */ : + --e_ > 0 ? traits::rfind_separator (*p_, e_ - 1) : + string_type::npos /* Leftmost empty component */; + + b_ = b_ == string_type::npos ? 0 : b_ + 1; + } + + return *this; + } + iterator operator++ (int) {iterator r (*this); operator++ (); return r;} + iterator + operator-- (int) {iterator r (*this); operator-- (); return r;} + string_type operator* () const { return string_type (*p_, b_, (e_ != string_type::npos ? e_ - b_ : e_)); diff --git a/tests/path/driver.cxx b/tests/path/driver.cxx index 30933ea..a0fe18d 100644 --- a/tests/path/driver.cxx +++ b/tests/path/driver.cxx @@ -92,12 +92,22 @@ main () assert (p.begin () == p.end ()); } { + path p; + assert (p.rbegin () == p.rend ()); + } + { path p ("foo"); path::iterator i (p.begin ()); assert (i != p.end () && *i == "foo"); assert (++i == p.end ()); } { + path p ("foo"); + path::reverse_iterator i (p.rbegin ()); + assert (i != p.rend () && *i == "foo"); + assert (++i == p.rend ()); + } + { path p ("foo/bar"); path::iterator i (p.begin ()); assert (i != p.end () && *i == "foo"); @@ -105,6 +115,13 @@ main () assert (++i == p.end ()); } { + path p ("foo/bar"); + path::reverse_iterator i (p.rbegin ()); + assert (i != p.rend () && *i == "bar"); + assert (++i != p.rend () && *i == "foo"); + assert (++i == p.rend ()); + } + { path p ("/foo/bar"); path::iterator i (p.begin ()); assert (i != p.end () && *i == ""); @@ -112,6 +129,14 @@ main () assert (++i != p.end () && *i == "bar"); assert (++i == p.end ()); } + { + path p ("/foo/bar"); + path::reverse_iterator i (p.rbegin ()); + assert (i != p.rend () && *i == "bar"); + assert (++i != p.rend () && *i == "foo"); + assert (++i != p.rend () && *i == ""); + assert (++i == p.rend ()); + } #ifndef _WIN32 { path p ("/"); @@ -119,6 +144,12 @@ main () assert (i != p.end () && *i == ""); assert (++i == p.end ()); } + { + path p ("/"); + path::reverse_iterator i (p.rbegin ()); + assert (i != p.rend () && *i == ""); + assert (++i == p.rend ()); + } #endif // iterator range construction @@ -197,11 +228,11 @@ main () // comparison // - assert (path ("./foo") == path("./foo")); - assert (path ("./boo") < path("./foo")); + assert (path ("./foo") == path ("./foo")); + assert (path ("./boo") < path ("./foo")); #ifdef _WIN32 - assert (path (".\\foo") == path("./FoO")); - assert (path (".\\boo") < path(".\\Foo")); + assert (path (".\\foo") == path ("./FoO")); + assert (path (".\\boo") < path (".\\Foo")); #endif // posix_string -- cgit v1.1