Path.h revision 533eae20118036f425f27bf0536ef0ccbb090b65
1//===- Path.h -------------------------------------------------------------===// 2// 3// The MCLinker Project 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// This file declares the mcld::sys::fs::Path. It follows TR2/boost 10// filesystem (v3), but modified to remove exception handling and the 11// path class. 12//===----------------------------------------------------------------------===// 13#ifndef MCLD_SUPPORT_PATH_H 14#define MCLD_SUPPORT_PATH_H 15 16#include <llvm/Support/raw_ostream.h> 17#include <mcld/Config/Config.h> 18 19#include <iosfwd> 20#include <functional> 21#include <string> 22#include <locale> 23 24namespace mcld { 25namespace sys { 26namespace fs { 27 28#if defined(MCLD_ON_WIN32) 29const char preferred_separator = '/'; 30const char separator = '/'; 31#else 32const char preferred_separator = '/'; 33const char separator = '/'; 34#endif 35 36const char colon = ':'; 37const char dot = '.'; 38 39/** \class Path 40 * \brief Path provides an abstraction for the path to a file or directory in 41 * the operating system's filesystem. 42 */ 43class Path 44{ 45public: 46 typedef char ValueType; 47 typedef std::string StringType; 48 49public: 50 Path(); 51 Path(const ValueType* s); 52 Path(const StringType &s); 53 Path(const Path& pCopy); 54 virtual ~Path(); 55 56 // ----- assignments ----- // 57 template <class InputIterator> 58 Path& assign(InputIterator begin, InputIterator end); 59 Path& assign(const StringType &s); 60 Path& assign(const ValueType* s, unsigned int length); 61 62 // ----- appends ----- // 63 template <class InputIterator> 64 Path& append(InputIterator begin, InputIterator end); 65 Path& append(const Path& pPath); 66 67 // ----- observers ----- // 68 bool empty() const; 69 70 bool isFromRoot() const; 71 bool isFromPWD() const; 72 73 const StringType& native() const { return m_PathName; } 74 StringType& native() { return m_PathName; } 75 76 const ValueType* c_str() const 77 { return m_PathName.c_str(); } 78 79 // ----- decomposition ----- // 80 Path parent_path() const; 81 Path filename() const; 82 Path stem() const; 83 Path extension() const; 84 85 // ----- generic form observers ----- // 86 StringType generic_string() const; 87 bool canonicalize(); 88 89public: 90 StringType::size_type m_append_separator_if_needed(); 91 void m_erase_redundant_separator(StringType::size_type sep_pos); 92 93protected: 94 StringType m_PathName; 95}; 96 97bool operator==(const Path& pLHS,const Path& pRHS); 98bool operator!=(const Path& pLHS,const Path& pRHS); 99Path operator+(const Path& pLHS, const Path& pRHS); 100 101//===----------------------------------------------------------------------===// 102// Non-member Functions 103//===----------------------------------------------------------------------===// 104bool exists(const Path &pPath); 105 106bool is_directory(const Path &pPath); 107 108template <class Char, class Traits> 109inline std::basic_ostream<Char, Traits>& 110operator<<(std::basic_ostream<Char, Traits>& pOS, const Path& pPath) 111{ 112 return pOS << pPath.native(); 113} 114 115template <class Char, class Traits> 116inline std::basic_istream<Char, Traits>& 117operator>>(std::basic_istream<Char, Traits>& pOS, Path& pPath) 118{ 119 return pOS >> pPath.native(); 120} 121 122inline llvm::raw_ostream& 123operator<<(llvm::raw_ostream& pOS, const Path& pPath) 124{ 125 return pOS << pPath.native(); 126} 127 128//===----------------------------------------------------------------------===// 129// class path member template implementation 130//===----------------------------------------------------------------------===// 131template <class InputIterator> 132Path& Path::assign(InputIterator begin, InputIterator end) 133{ 134 m_PathName.clear(); 135 if (begin != end) 136 m_PathName.append<InputIterator>(begin, end); 137 return *this; 138} 139 140template <class InputIterator> 141Path& Path::append(InputIterator begin, InputIterator end) 142{ 143 if (begin == end) 144 return *this; 145 StringType::size_type sep_pos(m_append_separator_if_needed()); 146 m_PathName.append<InputIterator>(begin, end); 147 if (sep_pos) 148 m_erase_redundant_separator(sep_pos); 149 return *this; 150} 151 152} // namespace of fs 153} // namespace of sys 154} // namespace of mcld 155 156//===----------------------------------------------------------------------===// 157// STL compatible functions 158//===----------------------------------------------------------------------===// 159namespace std { 160 161template<> 162struct less<mcld::sys::fs::Path> : public binary_function<mcld::sys::fs::Path, 163 mcld::sys::fs::Path, 164 bool> 165{ 166 bool operator() (const mcld::sys::fs::Path& pX,const mcld::sys::fs::Path& pY) const { 167 if (pX.generic_string().size() < pY.generic_string().size()) 168 return true; 169 return (pX.generic_string() < pY.generic_string()); 170 } 171}; 172 173} // namespace of std 174 175#endif 176 177