]> git.tdb.fi Git - libs/core.git/blob - source/fs/path.h
9bc93f6c003eab2db5a695c2a312c9b1db1fc4c8
[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 */
25 class Path
26 {
27 private:
28         typedef std::vector<std::string::size_type> PositionArray;
29
30 public:
31         class Iterator
32         {
33         private:
34                 const Path *path;
35                 PositionArray::const_iterator iter;
36                 bool end;
37
38                 Iterator(const Path &, bool = false);
39         public:
40                 static Iterator at_begin(const Path &p) { return Iterator(p); }
41                 static Iterator at_end(const Path &p) { return Iterator(p, true); }
42
43                 Iterator &operator++();
44                 Iterator &operator--();
45                 std::string operator*() const;
46                 bool operator==(const Iterator &i) const { return (iter==i.iter && end==i.end); }
47                 bool operator!=(const Iterator &i) const { return !(*this==i); }
48         };
49
50 private:
51         std::string path;
52         std::vector<std::string::size_type> separators;
53
54 public:
55         Path();
56         Path(const std::string &);
57         Path(const char *);
58 private:
59         void init(const std::string &);
60
61 public:
62         const std::string &str() const { return path; }
63
64         /// Returns the number of components in the path.
65         unsigned size() const;
66
67         bool empty() const { return path.empty(); }
68
69         /// Determines whether the path starts from the root directory
70         bool is_absolute() const;
71
72         /// Extracts a range of components from the path.
73         Path subpath(unsigned start, unsigned count = static_cast<unsigned>(-1)) const;
74
75         /// Concatenates this path with another one, with usual filesystem semantics
76         Path operator/(const Path &p) const;
77         Path &operator/=(const Path &);
78
79 private:
80         /** Adds a component to the path.  It must not contain the directory
81         separator character. */
82         void add_component(const std::string &);
83
84 public:
85         /** Extracts a single component from the path.  Negative indices count from
86         the end of the path. */
87         std::string operator[](int) const;
88
89         bool operator==(const Path &) const;
90         bool operator<(const Path &) const;
91         bool operator>(const Path &) const;
92         bool operator<=(const Path &other) const { return !(*this>other); }
93         bool operator>=(const Path &other) const { return !(*this<other); }
94         bool operator!=(const Path &other) const { return !(*this==other); }
95
96         Iterator begin() const { return Iterator::at_begin(*this); }
97         Iterator end() const { return Iterator::at_end(*this); }
98 };
99
100 inline std::ostream &operator<<(std::ostream &o, const Path &p) { o<<p.str(); return o; }
101
102 } // namespace FS
103 } // namespace Msp
104
105 #endif