]> git.tdb.fi Git - libs/core.git/blob - source/fs/path.h
Add Path::c_str() method
[libs/core.git] / source / fs / path.h
1 #ifndef MSP_FS_PATH_H_
2 #define MSP_FS_PATH_H_
3
4 #include <ostream>
5 #include <string>
6 #include <vector>
7
8 namespace Msp {
9 namespace FS {
10
11 enum
12 {
13 #ifdef WIN32
14         DIRSEP = '\\'
15 #else
16         DIRSEP = '/'
17 #endif
18 };
19
20 /**
21 Stores a filesystem path.  Paths are always stored in a normalized form; there
22 are never any "." or ".." components in the middle of the path, and relative
23 paths always begin with a single "." component or a sequence ".." components.
24 As a special case, calling the constructor with no arguments or with an empty
25 string will construct an empty path; this can be usedful as an invalid value.
26
27 A path can also be treated as an array of components, supporting indexing,
28 iteration and slicing.  In this context the root directory is treated as a
29 component of its own.
30 */
31 class Path
32 {
33 private:
34         typedef std::vector<std::string::size_type> PositionArray;
35
36 public:
37         class Iterator
38         {
39         private:
40                 const Path *path;
41                 PositionArray::const_iterator iter;
42                 bool end;
43
44                 Iterator(const Path &, bool = false);
45         public:
46                 static Iterator at_begin(const Path &p) { return Iterator(p); }
47                 static Iterator at_end(const Path &p) { return Iterator(p, true); }
48
49                 Iterator &operator++();
50                 Iterator &operator--();
51                 std::string operator*() const;
52                 bool operator==(const Iterator &i) const { return (iter==i.iter && end==i.end); }
53                 bool operator!=(const Iterator &i) const { return !(*this==i); }
54         };
55
56 private:
57         std::string path;
58         std::vector<std::string::size_type> separators;
59
60 public:
61         Path();
62         Path(const std::string &);
63         Path(const char *);
64 private:
65         void init(const std::string &);
66
67 public:
68         /// Returns the path as a string.
69         const std::string &str() const { return path; }
70
71         /// Returns the path as a pointer to a null-terminated string.
72         const char *c_str() const { return path.c_str(); }
73
74         /// Returns the number of components in the path.
75         unsigned size() const;
76
77         /** Indicates whether the path is empty.  This really means empty; a path
78         pointing to the current directory is not empty. */
79         bool empty() const { return path.empty(); }
80
81         /// Determines whether the path starts from the root directory.
82         bool is_absolute() const;
83
84         /// Extracts a range of components from the path.
85         Path subpath(unsigned start, unsigned count = static_cast<unsigned>(-1)) const;
86
87         /// Concatenates this path with another one, with usual filesystem semantics.
88         Path operator/(const Path &p) const;
89         Path &operator/=(const Path &);
90
91 private:
92         /** Adds a component to the path.  It must not contain the directory
93         separator character. */
94         void add_component(const std::string &);
95
96 public:
97         /** Extracts a single component from the path.  Negative indices count from
98         the end of the path. */
99         std::string operator[](int) const;
100
101         bool operator==(const Path &) const;
102         bool operator<(const Path &) const;
103         bool operator>(const Path &) const;
104         bool operator<=(const Path &other) const { return !(*this>other); }
105         bool operator>=(const Path &other) const { return !(*this<other); }
106         bool operator!=(const Path &other) const { return !(*this==other); }
107
108         Iterator begin() const { return Iterator::at_begin(*this); }
109         Iterator end() const { return Iterator::at_end(*this); }
110 };
111
112 inline std::ostream &operator<<(std::ostream &o, const Path &p) { o<<p.str(); return o; }
113
114 } // namespace FS
115 } // namespace Msp
116
117 #endif