From 6efb1b1ce3901c7d90402e8e828b07977fe425d0 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Sat, 9 Jul 2016 11:24:11 +0200 Subject: Add path::operator=/(string), path::size() --- butl/path | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++------- butl/path.ixx | 15 +++++++++++++ butl/path.txx | 31 ++++++++++++++++++++------- 3 files changed, 98 insertions(+), 16 deletions(-) diff --git a/butl/path b/butl/path index 193eae4..33c3d11 100644 --- a/butl/path +++ b/butl/path @@ -74,13 +74,20 @@ namespace butl static size_type find_separator (string_type const& s, size_type pos = 0) { - for (size_type n (s.size ()); pos < n; ++pos) + const C* r (find_separator (s.c_str () + pos, s.size () - pos)); + return r != nullptr ? r - s.c_str () : string_type::npos; + } + + static const C* + find_separator (const C* s, size_type n) + { + for (const C* e (s + n); s != e; ++s) { - if (is_separator (s[pos])) - return pos; + if (is_separator (*s)) + return s; } - return string_type::npos; + return nullptr; } static size_type @@ -360,10 +367,10 @@ namespace butl public: bool - empty () const - { - return this->path_.empty (); - } + empty () const {return this->path_.empty ();} + + size_type + size () const {return this->path_.size ();} // Return true if this path doesn't have any directories. Note // that "/foo" is not a simple path (it is "foo" in root directory) @@ -562,6 +569,15 @@ namespace butl basic_path& operator/= (basic_path const&); + // Append a single path component (must not contain directory separators) + // as a string, without first constructing the path object. + // + basic_path& + operator/= (string_type const&); + + basic_path& + operator/= (const C*); + basic_path operator+ (string_type const& s) const { @@ -569,6 +585,12 @@ namespace butl } basic_path + operator+ (const C* s) const + { + return basic_path (this->path_ + s); + } + + basic_path operator+ (C c) const { return basic_path (this->path_ + c); @@ -582,6 +604,13 @@ namespace butl } basic_path& + operator+= (const C* s) + { + this->path_ += s; + return *this; + } + + basic_path& operator+= (C c) { this->path_ += c; @@ -622,6 +651,11 @@ namespace butl init (this->path_); } + // Common implementation for operator=/(). + // + void + combine (const C*, size_type); + private: template friend P butl::path_cast (const basic_path&); @@ -648,6 +682,24 @@ namespace butl return r; } + template + inline basic_path + operator/ (basic_path const& x, std::basic_string const& y) + { + basic_path r (x); + r /= y; + return r; + } + + template + inline basic_path + operator/ (basic_path const& x, const C* y) + { + basic_path r (x); + r /= y; + return r; + } + template inline bool operator== (const basic_path& x, const basic_path& y) diff --git a/butl/path.ixx b/butl/path.ixx index 1628ece..48d6576 100644 --- a/butl/path.ixx +++ b/butl/path.ixx @@ -233,4 +233,19 @@ namespace butl return string (); } #endif + + template + inline void basic_path:: + combine (const C* r, size_type rn) + { + size_type ln (this->path_.size ()); + + if (ln != 0 && rn != 0) + { + if (!traits::is_separator (this->path_[ln - 1])) + this->path_ += traits::directory_separator; + } + + this->path_.append (r, rn); + } } diff --git a/butl/path.txx b/butl/path.txx index 35c6956..94fbd90 100644 --- a/butl/path.txx +++ b/butl/path.txx @@ -61,16 +61,31 @@ namespace butl if (r.absolute () && !this->path_.empty ()) // Allow ('' / '/foo'). throw invalid_basic_path (r.path_); - if (this->path_.empty () || r.path_.empty ()) - { - this->path_ += r.path_; - return *this; - } + combine (r.path_.c_str (), r.path_.size ()); + return *this; + } + + template + basic_path& basic_path:: + operator/= (string_type const& r) + { + if (traits::find_separator (r) != string_type::npos) + throw invalid_basic_path (r); + + combine (r.c_str (), r.size ()); + return *this; + } + + template + basic_path& basic_path:: + operator/= (const C* r) + { + size_type rn (string_type::traits_type::length (r)); - if (!traits::is_separator (this->path_[this->path_.size () - 1])) - this->path_ += traits::directory_separator; + if (traits::find_separator (r, rn) != nullptr) + throw invalid_basic_path (r); - this->path_ += r.path_; + combine (r, rn); return *this; } -- cgit v1.1