diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2015-06-18 14:41:45 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2015-06-18 14:41:45 +0200 |
commit | 63e7a4a77cb8ceed7b42561fe3202b0b48d86db6 (patch) | |
tree | bde5a79522225f32ec188ba46d0834486c30f00f /build/path | |
parent | 28c82c861e38fe05a25e916563e0551ed8fce91e (diff) |
Move path and filesystem from build2 to libbutl
Diffstat (limited to 'build/path')
-rw-r--r-- | build/path | 553 |
1 files changed, 0 insertions, 553 deletions
diff --git a/build/path b/build/path deleted file mode 100644 index f107391..0000000 --- a/build/path +++ /dev/null @@ -1,553 +0,0 @@ -// file : build/path -*- C++ -*- -// copyright : Copyright (c) 2014-2015 Code Synthesis Ltd -// license : MIT; see accompanying LICENSE file - -#ifndef BUILD_PATH -#define BUILD_PATH - -#include <string> -#include <cstddef> // ptrdiff_t -#include <ostream> -#include <utility> // move -#include <iterator> -#include <exception> -#include <functional> // hash - -namespace build -{ - template <typename C> - struct path_traits - { - typedef std::basic_string<C> string_type; - typedef typename string_type::size_type size_type; - - // Canonical directory and path seperators. - // -#ifdef _WIN32 - static C const directory_separator = '\\'; - static C const path_separator = ';'; -#else - static C const directory_separator = '/'; - static C const path_separator = ':'; -#endif - - // Directory separator tests. On some platforms there - // could be multiple seperators. For example, on Windows - // we check for both '/' and '\'. - // - static bool - is_separator (C c) - { -#ifdef _WIN32 - return c == '\\' || c == '/'; -#else - return c == '/'; -#endif - } - - static size_type - find_separator (string_type const& s, size_type pos = 0) - { - for (size_type n (s.size ()); pos < n; ++pos) - { - if (is_separator (s[pos])) - return pos; - } - - return string_type::npos; - } - - static size_type - rfind_separator (string_type const& s, size_type pos = string_type::npos) - { - if (pos == string_type::npos) - pos = s.size (); - else - pos++; - - for (; pos > 0; --pos) - { - if (is_separator (s[pos - 1])) - return pos - 1; - } - - return string_type::npos; - } - - // Return the position of '.' or npos if there is no extension. - // - static size_type - find_extension (string_type const& s) - { - size_type i (s.size ()); - - for (; i > 0; --i) - { - C c (s[i - 1]); - - if (c == '.') - break; - - if (is_separator (c)) - { - i = 0; - break; - } - } - - // Weed out paths like ".txt" (and "/.txt") and "txt.". - // - if (i > 1 && !is_separator (s[i - 2]) && i != s.size ()) - return i - 1; - else - return string_type::npos; - } - - static int - compare (string_type const& l, string_type const& r) - { - size_type ln (l.size ()), rn (r.size ()), n (ln < rn ? ln : rn); - for (size_type i (0); i != n; ++i) - { -#ifdef _WIN32 - C lc (tolower (l[i])), rc (tolower (r[i])); -#else - C lc (l[i]), rc (r[i]); -#endif - if (is_separator (lc) && is_separator (rc)) - continue; - - if (lc < rc) return -1; - if (lc > rc) return 1; - } - - 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 - tolower (C); -#endif - }; - - template <typename C> - class invalid_basic_path; - - template <typename C, typename K> - class basic_path; - - template <typename C> - class path_data; - - template <typename C> - struct dir_path_kind; - - template <typename C> - struct any_path_kind - { - typedef path_data<C> base_type; - typedef basic_path<C, dir_path_kind<C>> dir_type; - }; - - template <typename C> - struct dir_path_kind - { - typedef basic_path<C, any_path_kind<C>> base_type; - typedef basic_path<C, dir_path_kind<C>> dir_type; - }; - - typedef basic_path<char, any_path_kind<char>> path; - typedef basic_path<char, dir_path_kind<char>> dir_path; - typedef invalid_basic_path<char> invalid_path; - - typedef basic_path<wchar_t, any_path_kind<wchar_t>> wpath; - typedef basic_path<wchar_t, dir_path_kind<wchar_t>> dir_wpath; - typedef invalid_basic_path<wchar_t> invalid_wpath; - - // - // - class invalid_path_base: std::exception - { - public: - virtual char const* - what () const throw (); - }; - - template <typename C> - class invalid_basic_path: public invalid_path_base - { - public: - typedef std::basic_string<C> string_type; - - invalid_basic_path (C const* p): path_ (p) {} - invalid_basic_path (string_type const& p): path_ (p) {} - ~invalid_basic_path () throw () {} - - string_type const& - path () const - { - return path_; - } - - private: - string_type path_; - }; - - template <typename C> - class path_data - { - public: - typedef std::basic_string<C> string_type; - - path_data () = default; - - explicit - path_data (string_type s): path_ (std::move (s)) {} - - protected: - string_type path_; - }; - - template <typename C, typename K> - class basic_path: public K::base_type - { - public: - typedef std::basic_string<C> 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<C> traits; - - // 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. - // - basic_path () {}; - - explicit - basic_path (C const* s): base_type (s) {init ();} - - basic_path (C const* s, size_type n) - : base_type (string_type (s, n)) {init ();} - - explicit - basic_path (string_type s): base_type (std::move (s)) {init ();} - - basic_path (const string_type& s, size_type n) - : base_type (string_type (s, 0, n)) {init ();} - - basic_path (const string_type& s, size_type p, size_type n) - : base_type (string_type (s, p, n)) {init ();} - - void - swap (basic_path& p) - { - this->path_.swap (p.path_); - } - - void - clear () - { - this->path_.clear (); - } - - // 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&); - - public: - bool - empty () const - { - return this->path_.empty (); - } - - bool - absolute () const; - - bool - relative () const - { - return !absolute (); - } - - bool - root () const; - - // Return true if *this is a sub-path of the specified path (i.e., - // the specified path is a prefix). Expects both paths to be - // normalized. Note that this function returns true if the paths - // are equal. Empty path is considered a prefix of any path. - // - bool - sub (const basic_path&) const; - - // Return true if *this is a super-path of the specified path (i.e., - // the specified path is a suffix). Expects both paths to be - // normalized. Note that this function returns true if the paths - // are equal. Empty path is considered a suffix of any path. - // - bool - sup (const basic_path&) const; - - public: - // Return the path without the directory part. - // - basic_path - leaf () const; - - // Return the path without the specified directory part. Throws - // invalid_path if the directory is not a prefix of *this. Expects - // both paths to be normalized. - // - basic_path - leaf (basic_path const&) const; - - // Return the directory part of the path or empty path if - // there is no directory. - // - 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. - // - dir_type - directory (basic_path const&) const; - - // Return the root directory of the path or empty path if - // the directory is not absolute. - // - dir_type - root_directory () const; - - // Return the path without the extension, if any. - // - basic_path - base () const; - - // Return the extension or NULL if not present. - // - const C* - extension () const; - - // Return a path relative to the specified path that is equivalent - // to *this. Throws invalid_path if a relative path cannot be derived - // (e.g., paths are on different drives on Windows). - // - basic_path - relative (basic_path) const; - - // Iteration over path components. - // - public: - struct iterator - { - typedef string_type value_type; - typedef string_type* pointer; - typedef string_type& reference; - typedef std::ptrdiff_t difference_type; - typedef std::forward_iterator_tag iterator_category; - - typedef typename string_type::size_type size_type; - - iterator (): p_ (nullptr) {} - iterator (const string_type& p, size_type b, size_type e) - : p_ (&p), b_ (b), e_ (e) {} - - iterator& - operator++ () - { - b_ = e_; - - if (b_ != string_type::npos) - e_ = traits::find_separator (*p_, ++b_); - - return *this; - } - - iterator - operator++ (int) {iterator r (*this); return ++r;} - - string_type operator* () const - { - return string_type (*p_, b_, (e_ != string_type::npos ? e_ - b_ : e_)); - } - - friend bool - operator== (const iterator& x, const iterator& y) - { - return x.p_ == y.p_ && x.b_ == y.b_ && x.e_ == y.e_; - } - - friend bool - operator!= (const iterator& x, const iterator& y) {return !(x == y);} - - private: - // b != npos && e == npos - last component - // b == npos && e == npos - one past last component (end) - // - const string_type* p_; - size_type b_; - size_type e_; - }; - - iterator begin () const; - iterator end () const; - - public: - // Normalize the path. This includes collapsing the '.' and '..' - // directories if possible, collapsing multiple directory - // separators, and converting all directory separators to the - // canonical form. Returns *this. - // - basic_path& - normalize (); - - // Make the path absolute using the current directory unless - // it is already absolute. - // - basic_path& - complete (); - - public: - basic_path& - operator/= (basic_path const&); - - basic_path - operator+ (string_type const& s) const - { - return basic_path (this->path_ + s); - } - - basic_path - operator+ (C c) const - { - return basic_path (this->path_ + c); - } - - basic_path& - operator+= (string_type const& s) - { - this->path_ += s; - return *this; - } - - basic_path& - operator+= (C c) - { - this->path_ += c; - return *this; - } - - // Note that comparison is case-insensitive if the filesystem is - // not case-sensitive (e.g., Windows). - // - bool - operator== (basic_path const& x) const - { - return traits::compare (this->path_, x.path_) == 0; - } - - bool - operator!= (basic_path const& x) const - { - return !(*this == x); - } - - bool - operator< (basic_path const& x) const - { - return traits::compare (this->path_, x.path_) < 0; - } - - public: - const string_type& - string () const - { - return this->path_; - } - - // If possible, return a POSIX representation of the path. For example, - // for a Windows path in the form foo\bar this function will return - // foo/bar. If it is not possible to create a POSIX representation for - // this path (e.g., c:\foo), this function will throw the invalid_path - // exception. - // - string_type - posix_string () const; - - private: - void - init (); - }; - - template <typename C, typename K> - inline basic_path<C, K> - operator/ (basic_path<C, K> const& x, basic_path<C, K> const& y) - { - basic_path<C, K> r (x); - r /= y; - return r; - } - - // Additional operators for certain path kind combinations. - // - template <typename C> - inline basic_path<C, any_path_kind<C>> - operator/ (basic_path<C, dir_path_kind<C>> const& x, - basic_path<C, any_path_kind<C>> const& y) - { - basic_path<C, any_path_kind<C>> r (x); - r /= y; - return r; - } - - // IO - // - - /* - template <typename C, typename K> - inline std::basic_ostream<C>& - operator<< (std::basic_ostream<C>& os, basic_path<C, K> const& p) - { - return os << p.string (); - } - */ -} - -namespace std -{ - template <typename C, typename K> - struct hash<build::basic_path<C, K>>: hash<basic_string<C>> - { - size_t - operator() (const build::basic_path<C, K>& p) const noexcept - { - return hash<basic_string<C>>::operator() (p.string ()); - } - }; -} - -#include <build/path.ixx> -#include <build/path.txx> - -#endif // BUILD_PATH |