blob: 33f470523155bed79829a15dc4c7052eb698425d [file] [log] [blame]
//===- Path.h -------------------------------------------------------------===//
//
// The MCLinker Project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// This file declares the mcld::sys::fs::Path. It follows TR2/boost
// filesystem (v3), but modified to remove exception handling and the
// path class.
//===----------------------------------------------------------------------===//
#ifndef MCLD_SUPPORT_PATH_H_
#define MCLD_SUPPORT_PATH_H_
#include "mcld/Config/Config.h"
#include <llvm/Support/raw_ostream.h>
#include <iosfwd>
#include <functional>
#include <string>
#include <locale>
namespace mcld {
namespace sys {
namespace fs {
#if defined(MCLD_ON_WIN32)
const char preferred_separator = '/';
const char separator = '/';
#else
const char preferred_separator = '/';
const char separator = '/';
#endif
const char colon = ':';
const char dot = '.';
/** \class Path
* \brief Path provides an abstraction for the path to a file or directory in
* the operating system's filesystem.
*/
class Path {
public:
typedef char ValueType;
typedef std::string StringType;
public:
Path();
explicit Path(const ValueType* s);
explicit Path(const StringType& s);
Path(const Path& pCopy);
virtual ~Path();
// ----- assignments ----- //
template <class InputIterator>
Path& assign(InputIterator begin, InputIterator end);
Path& assign(const StringType& s);
Path& assign(const ValueType* s, unsigned int length);
// ----- appends ----- //
template <class InputIterator>
Path& append(InputIterator begin, InputIterator end);
Path& append(const Path& pPath);
Path& append(const StringType& pPath);
// ----- observers ----- //
bool empty() const;
bool isFromRoot() const;
bool isFromPWD() const;
const StringType& native() const { return m_PathName; }
StringType& native() { return m_PathName; }
const ValueType* c_str() const { return m_PathName.c_str(); }
// ----- decomposition ----- //
Path parent_path() const;
Path filename() const;
Path stem() const;
Path extension() const;
// ----- generic form observers ----- //
StringType generic_string() const;
bool canonicalize();
public:
StringType::size_type m_append_separator_if_needed();
void m_erase_redundant_separator(StringType::size_type sep_pos);
protected:
StringType m_PathName;
};
bool operator==(const Path& pLHS, const Path& pRHS);
bool operator!=(const Path& pLHS, const Path& pRHS);
Path operator+(const Path& pLHS, const Path& pRHS);
//===----------------------------------------------------------------------===//
// Non-member Functions
//===----------------------------------------------------------------------===//
bool exists(const Path& pPath);
bool is_directory(const Path& pPath);
template <class Char, class Traits>
inline std::basic_ostream<Char, Traits>& operator<<(
std::basic_ostream<Char, Traits>& pOS,
const Path& pPath) {
return pOS << pPath.native();
}
template <class Char, class Traits>
inline std::basic_istream<Char, Traits>& operator>>(
std::basic_istream<Char, Traits>& pOS,
Path& pPath) {
return pOS >> pPath.native();
}
inline llvm::raw_ostream& operator<<(llvm::raw_ostream& pOS,
const Path& pPath) {
return pOS << pPath.native();
}
//===----------------------------------------------------------------------===//
// class path member template implementation
//===----------------------------------------------------------------------===//
template <class InputIterator>
Path& Path::assign(InputIterator begin, InputIterator end) {
m_PathName.clear();
if (begin != end)
m_PathName.append<InputIterator>(begin, end);
return *this;
}
template <class InputIterator>
Path& Path::append(InputIterator begin, InputIterator end) {
if (begin == end)
return *this;
StringType::size_type sep_pos(m_append_separator_if_needed());
m_PathName.append<InputIterator>(begin, end);
if (sep_pos)
m_erase_redundant_separator(sep_pos);
return *this;
}
} // namespace fs
} // namespace sys
} // namespace mcld
//===----------------------------------------------------------------------===//
// STL compatible functions
//===----------------------------------------------------------------------===//
namespace std {
template <>
struct less<mcld::sys::fs::Path>
: public binary_function<mcld::sys::fs::Path, mcld::sys::fs::Path, bool> {
bool operator()(const mcld::sys::fs::Path& pX,
const mcld::sys::fs::Path& pY) const {
if (pX.generic_string().size() < pY.generic_string().size())
return true;
return (pX.generic_string() < pY.generic_string());
}
};
} // namespace std
#endif // MCLD_SUPPORT_PATH_H_