diff options
-rw-r--r-- | butl/path | 11 | ||||
-rw-r--r-- | butl/path.ixx | 20 | ||||
-rw-r--r-- | tests/path/driver.cxx | 36 |
3 files changed, 66 insertions, 1 deletions
@@ -235,6 +235,8 @@ namespace butl typedef path_traits<C> traits; + struct iterator; + // Construct special empty path. Note that we have to provide our // own implementation rather than using '=default' to make clang // allow default-initialized const instances of this type. @@ -256,6 +258,11 @@ namespace butl basic_path (const string_type& s, size_type p, size_type n) : base_type (string_type (s, p, n)) {init ();} + // Create a path as a sub-path identified by the [begin, end) + // range of components. + // + basic_path (const iterator& begin, const iterator& end); + void swap (basic_path& p) { @@ -399,7 +406,7 @@ namespace butl } iterator - operator++ (int) {iterator r (*this); return ++r;} + operator++ (int) const {iterator r (*this); return ++r;} string_type operator* () const { @@ -416,6 +423,8 @@ namespace butl operator!= (const iterator& x, const iterator& y) {return !(x == y);} private: + friend class basic_path; + // b != npos && e == npos - last component // b == npos && e == npos - one past last component (end) // diff --git a/butl/path.ixx b/butl/path.ixx index 3e8a9cc..7ce8c63 100644 --- a/butl/path.ixx +++ b/butl/path.ixx @@ -147,6 +147,26 @@ namespace butl } template <typename C, typename K> + inline basic_path<C, K>:: + basic_path (const iterator& b, const iterator& e) + { + //assert (b.p_ == e.p_); + + if (b != e) + { + this->path_.assign ( + *b.p_, b.b_, (e.b_ != string_type::npos ? e.b_ - b.b_ - 1 : e.b_)); + +#ifndef _WIN32 + if (this->path_.empty ()) + this->path_ = '/'; +#endif + + // No init() should be necessary. + } + } + + template <typename C, typename K> inline basic_path<C, K>& basic_path<C, K>:: complete () { diff --git a/tests/path/driver.cxx b/tests/path/driver.cxx index c83fd12..302968d 100644 --- a/tests/path/driver.cxx +++ b/tests/path/driver.cxx @@ -112,12 +112,48 @@ main () assert (++i != p.end () && *i == "bar"); assert (++i == p.end ()); } +#ifndef _WIN32 { path p ("/"); path::iterator i (p.begin ()); assert (i != p.end () && *i == ""); assert (++i == p.end ()); } +#endif + + // iterator range construction + // + { + path p; + assert (path (p.begin (), p.end ()) == p); + } + { + path p ("foo"); + assert (path (p.begin (), p.end ()) == p); + assert (path (p.begin ()++, p.end ()) == path ()); + } + { + path p ("foo/bar"); + assert (path (p.begin (), p.end ()) == p); + assert (path (p.begin ()++, p.end ()) == path ("bar")); + assert (path (p.begin (), p.begin ()++) == path ("foo")); + } + { + path p ("/foo/bar"); + assert (path (p.begin (), p.end ()) == p); + assert (path (p.begin ()++, p.end ()) == path ("foo/bar")); + assert (path ((p.begin ()++)++, p.end ()) == path ("bar")); + assert (path (p.begin (), p.begin ()++) == path ("/")); + assert (path (p.begin ()++, (p.begin ()++)++) == path ("foo")); + assert (path ((p.begin ()++)++, ((p.begin ()++)++)++) == path ("bar")); + } +#ifndef _WIN32 + { + path p ("/"); + assert (path (p.begin (), p.end ()) == p); + assert (path (p.begin ()++, p.end ()) == path ()); + } +#endif // operator/ // |