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