From ace1743f7f78bb13f99553d6e97ad1beecf1ba99 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 13 Apr 2015 15:50:17 +0200 Subject: Add separate type to represent directory paths --- build/path | 170 +++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 108 insertions(+), 62 deletions(-) (limited to 'build/path') diff --git a/build/path b/build/path index 1a62287..d153ed7 100644 --- a/build/path +++ b/build/path @@ -14,9 +14,6 @@ namespace build { template - class basic_path; - - template struct path_traits { typedef std::basic_string string_type; @@ -125,6 +122,15 @@ namespace build return ln < rn ? -1 : (ln > rn ? 1 : 0); } + // Get/set current working directory. Throw std::system_error + // to report the underlying OS errors. + // + static string_type + current (); + + static void + current (string_type const&); + private: #ifdef _WIN32 static C @@ -135,10 +141,35 @@ namespace build template class invalid_basic_path; - typedef basic_path path; + template + class basic_path; + + template + class path_data; + + template + struct dir_path_kind; + + template + struct any_path_kind + { + typedef path_data base_type; + typedef basic_path> dir_type; + }; + + template + struct dir_path_kind + { + typedef basic_path> base_type; + typedef basic_path> dir_type; + }; + + typedef basic_path> path; + typedef basic_path> dir_path; typedef invalid_basic_path invalid_path; - typedef basic_path wpath; + typedef basic_path> wpath; + typedef basic_path> dir_wpath; typedef invalid_basic_path invalid_wpath; // @@ -171,66 +202,68 @@ namespace build }; template - class basic_path + class path_data + { + public: + typedef std::basic_string string_type; + + path_data () = default; + + explicit + path_data (string_type s): path_ (std::move (s)) {} + + protected: + string_type path_; + }; + + template + class basic_path: public K::base_type { public: typedef std::basic_string string_type; typedef typename string_type::size_type size_type; + typedef typename K::base_type base_type; + typedef typename K::dir_type dir_type; + typedef path_traits traits; // Construct special empty path. // - basic_path () - { - } + basic_path () = default; explicit - basic_path (C const* s) - : path_ (s) - { - init (); - } + basic_path (C const* s): base_type (s) {init ();} basic_path (C const* s, size_type n) - : path_ (s, n) - { - init (); - } + : base_type (string_type (s, n)) {init ();} explicit - basic_path (string_type s) - : path_ (std::move (s)) - { - init (); - } + basic_path (string_type s): base_type (std::move (s)) {init ();} basic_path (const string_type& s, size_type n) - : path_ (s, 0, n) - { - init (); - } + : base_type (string_type (s, 0, n)) {init ();} basic_path (const string_type& s, size_type p, size_type n) - : path_ (s, p, n) - { - init (); - } + : base_type (string_type (s, p, n)) {init ();} void swap (basic_path& p) { - path_.swap (p.path_); + this->path_.swap (p.path_); } void clear () { - path_.clear (); + this->path_.clear (); } - static basic_path - current (); + // Get/set current working directory. Throw std::system_error + // to report the underlying OS errors. + // + static dir_type + current () {return dir_type (traits::current ());} static void current (basic_path const&); @@ -239,7 +272,7 @@ namespace build bool empty () const { - return path_.empty (); + return this->path_.empty (); } bool @@ -286,20 +319,20 @@ namespace build // Return the directory part of the path or empty path if // there is no directory. // - basic_path + dir_type directory () const; // Return the directory part of the path without the specified // leaf part. Throws invalid_path if the leaf is not a suffix of // *this. Expects both paths to be normalized. // - basic_path + dir_type directory (basic_path const&) const; // Return the root directory of the path or empty path if // the directory is not absolute. // - basic_path + dir_type root_directory () const; // Return the path without the extension, if any. @@ -335,40 +368,32 @@ namespace build complete (); public: - basic_path - operator/ (basic_path const& x) const - { - basic_path r (*this); - r /= x; - return r; - } - basic_path& operator/= (basic_path const&); basic_path operator+ (string_type const& s) const { - return basic_path (path_ + s); + return basic_path (this->path_ + s); } basic_path operator+ (C c) const { - return basic_path (path_ + c); + return basic_path (this->path_ + c); } basic_path& operator+= (string_type const& s) { - path_ += s; + this->path_ += s; return *this; } basic_path& operator+= (C c) { - path_ += c; + this->path_ += c; return *this; } @@ -378,7 +403,7 @@ namespace build bool operator== (basic_path const& x) const { - return traits::compare (path_, x.path_) == 0; + return traits::compare (this->path_, x.path_) == 0; } bool @@ -390,14 +415,14 @@ namespace build bool operator< (basic_path const& x) const { - return traits::compare (path_, x.path_) < 0; + return traits::compare (this->path_, x.path_) < 0; } public: const string_type& string () const { - return path_; + return this->path_; } // If possible, return a POSIX representation of the path. For example, @@ -412,15 +437,36 @@ namespace build private: void init (); - - private: - string_type path_; }; - /* + template + inline basic_path + operator/ (basic_path const& x, basic_path const& y) + { + basic_path r (x); + r /= y; + return r; + } + + // Additional operators for certain path kind combinations. + // template + inline basic_path> + operator/ (basic_path> const& x, + basic_path> const& y) + { + basic_path> r (x); + r /= y; + return r; + } + + // IO + // + + /* + template inline std::basic_ostream& - operator<< (std::basic_ostream& os, basic_path const& p) + operator<< (std::basic_ostream& os, basic_path const& p) { return os << p.string (); } @@ -429,11 +475,11 @@ namespace build namespace std { - template - struct hash>: hash> + template + struct hash>: hash> { size_t - operator() (const build::basic_path& p) const noexcept + operator() (const build::basic_path& p) const noexcept { return hash>::operator() (p.string ()); } -- cgit v1.1