vsg  1.1.0
VulkanSceneGraph library
Path.h
1 #pragma once
2 
3 /* <editor-fold desc="MIT License">
4 
5 Copyright(c) 2022 Robert Osfield
6 
7 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
8 
9 The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10 
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
12 
13 </editor-fold> */
14 
15 #include <vsg/io/convert_utf.h>
16 
17 #include <string>
18 
19 namespace vsg
20 {
21 
22  enum FileType
23  {
24  FILE_NOT_FOUND = 0,
25  REGULAR_FILE,
26  DIRECTORY
27  };
28 
31  class VSG_DECLSPEC Path
32  {
33  public:
34 #if defined(_MSC_VER) || defined(__MINGW32__)
35  using value_type = wchar_t;
36  static constexpr value_type windows_separator = L'\\';
37  static constexpr value_type posix_separator = L'/';
38  static constexpr value_type preferred_separator = windows_separator;
39  static constexpr value_type alternate_separator = posix_separator;
40  static constexpr const value_type* separators = L"/\\";
41 #else
42  using value_type = char;
43  static constexpr value_type windows_separator = '\\';
44  static constexpr value_type posix_separator = '/';
45  static constexpr value_type preferred_separator = posix_separator;
46  static constexpr value_type alternate_separator = windows_separator;
47  static constexpr const value_type* separators = "/\\";
48 #endif
49  using string_type = std::basic_string<value_type>;
50 
51  using size_type = size_t;
52  using reference = value_type&;
53  using const_reference = const value_type&;
54  using iterator = string_type::iterator;
55  using const_iterator = string_type::const_iterator;
56  using pointer = value_type*;
57  using const_pointer = const value_type*;
58 
59  static const size_type npos = static_cast<size_type>(-1);
60 
61  Path();
62  Path(const Path& path);
63  Path(const std::string& str);
64  Path(const char* str);
65  Path(const std::wstring& str);
66  Path(const wchar_t* str);
67 
68  iterator begin() { return _string.begin(); }
69  iterator end() { return _string.end(); }
70  const_iterator begin() const { return _string.begin(); }
71  const_iterator end() const { return _string.end(); }
72 
73  Path& assign(const Path& path);
74  Path& assign(const std::string& str);
75  Path& assign(const char* str);
76  Path& assign(const std::wstring& str);
77  Path& assign(const wchar_t* str);
78 
79  Path& operator=(const Path& path) { return assign(path); }
80  Path& operator=(const std::string& str) { return assign(str); }
81  Path& operator=(const char* str) { return assign(str); }
82  Path& operator=(const std::wstring& str) { return assign(str); }
83  Path& operator=(const wchar_t* str) { return assign(str); }
84 
85  int compare(const Path& rhs) const { return _string.compare(rhs._string); }
86  int compare(size_type pos, size_type n, const Path& rhs) const { return _string.compare(pos, n, rhs._string); }
87 
88  int compare(const char* rhs) const { return _string.compare(convert_utf<string_type>(rhs)); }
89  int compare(const wchar_t* rhs) const { return _string.compare(convert_utf<string_type>(rhs)); }
90  int compare(size_type pos, size_type n, const char* rhs) const { return _string.compare(pos, n, convert_utf<string_type>(rhs)); }
91  int compare(size_type pos, size_type n, const wchar_t* rhs) const { return _string.compare(pos, n, convert_utf<string_type>(rhs)); }
92 
93  bool operator==(const Path& rhs) const { return compare(rhs) == 0; }
94  bool operator!=(const Path& rhs) const { return compare(rhs) != 0; }
95  bool operator<(const Path& rhs) const { return compare(rhs) < 0; }
96 
97  bool operator==(const char* rhs) const { return compare(convert_utf<string_type>(rhs)) == 0; }
98  bool operator!=(const char* rhs) const { return compare(convert_utf<string_type>(rhs)) != 0; }
99 
100  bool operator==(const wchar_t* rhs) const { return compare(convert_utf<string_type>(rhs)) == 0; }
101  bool operator!=(const wchar_t* rhs) const { return compare(convert_utf<string_type>(rhs)) != 0; }
102 
103  explicit operator bool() const noexcept { return !_string.empty(); }
104  bool empty() const { return _string.empty(); }
105  size_type size() const { return _string.size(); }
106  size_type length() const { return _string.size(); }
107 
108  inline std::string string() const
109  {
110  std::string dest;
111  convert_utf(_string, dest);
112  return dest;
113  }
114  inline std::wstring wstring() const
115  {
116  std::wstring dest;
117  convert_utf(_string, dest);
118  return dest;
119  }
120 
121  inline const string_type& native() const noexcept { return _string; }
122  inline operator const string_type&() const noexcept { return _string; }
123  inline const value_type* c_str() const noexcept { return _string.c_str(); }
124 #if defined(__MINGW32__)
125  inline operator const value_type*() const noexcept
126  {
127  return _string.c_str();
128  }
129 #endif
130 
131  reference operator[](size_type pos)
132  {
133  return _string[pos];
134  }
135  const_reference operator[](size_type pos) const { return _string[pos]; }
136 
137  void clear() noexcept { _string.clear(); }
138  void swap(Path& rhs) noexcept { return _string.swap(rhs._string); }
139 
141  Path& concat(const Path& path)
142  {
143  _string.append(path._string);
144  return *this;
145  }
146 
148  Path& concat(char c)
149  {
150  _string.push_back(c);
151  return *this;
152  }
153 
155  Path& operator+=(const Path& path) { return concat(path); }
156 
158  Path& append(const Path& path);
159 
161  Path& operator/=(const Path& path) { return append(path); }
162 
163  Path substr(size_type pos, size_type len = Path::npos) const { return Path(_string.substr(pos, len)); }
164 
165  size_type find(const Path& s, size_type pos = 0) const { return _string.find(s._string, pos); }
166  size_type find(const char* s, size_type pos = 0) const { return _string.find(convert_utf<string_type>(s), pos); }
167  size_type find(const wchar_t* s, size_type pos = 0) const { return _string.find(convert_utf<string_type>(s), pos); }
168 
169  size_type find_first_of(const Path& s, size_type pos = 0) const { return _string.find_first_of(s._string, pos); }
170  size_type find_first_of(const char* s, size_type pos = 0) const { return find_first_of(convert_utf<string_type>(s), pos); }
171  size_type find_first_of(const char c, size_type pos = 0) const { return find_first_of(convert_utf<string_type>(c), pos); }
172  size_type find_first_of(const wchar_t* s, size_type pos = 0) const { return find_first_of(convert_utf<string_type>(s), pos); }
173  size_type find_first_of(const wchar_t c, size_type pos = 0) const { return find_first_of(convert_utf<string_type>(c), pos); }
174 
175  size_type find_last_of(const Path& s, size_type pos = npos) const { return _string.find_last_of(s._string, pos); }
176  size_type find_last_of(const char* s, size_type pos = npos) const { return find_last_of(convert_utf<string_type>(s), pos); }
177  size_type find_last_of(const char c, size_type pos = npos) const { return find_last_of(convert_utf<string_type>(c), pos); }
178  size_type find_last_of(const wchar_t* s, size_type pos = npos) const { return find_last_of(convert_utf<string_type>(s), pos); }
179  size_type find_last_of(const wchar_t c, size_type pos = npos) const { return find_last_of(convert_utf<string_type>(c), pos); }
180 
181  Path& replace(size_type pos, size_type n, const Path& str);
182  Path& replace(size_type pos, size_type n, const std::string& str);
183  Path& replace(size_type pos, size_type n, const std::wstring& str);
184  Path& replace(size_type pos, size_type n, const char* str);
185  Path& replace(size_type pos, size_type n, const wchar_t* str);
186 
187  Path& erase(size_t pos = 0, size_t len = Path::npos);
188 
189  FileType type() const;
190 
191  Path lexically_normal() const;
192 
193  protected:
194  string_type _string;
195  };
196  VSG_type_name(vsg::Path);
197 
199  inline Path operator+(const Path& lhs, const Path& rhs)
200  {
201  Path path(lhs);
202  return path.concat(rhs);
203  }
204 
206  inline Path operator/(const Path& lhs, const Path& rhs)
207  {
208  Path path(lhs);
209  return path /= rhs;
210  }
211 
212  using Paths = std::vector<Path>;
213  using PathObjects = std::map<Path, ref_ptr<Object>>;
214 
216  extern VSG_DECLSPEC Path filePath(const Path& path);
217 
219  extern VSG_DECLSPEC Path fileExtension(const Path& path);
220 
223  extern VSG_DECLSPEC Path lowerCaseFileExtension(const Path& path, bool pruneExtras = true);
224 
226  extern VSG_DECLSPEC Path simpleFilename(const Path& path);
227 
229  extern VSG_DECLSPEC bool trailingRelativePath(const Path& path);
230 
232  extern VSG_DECLSPEC Path removeExtension(const Path& path);
233 
234 } // namespace vsg
Definition: Path.h:32
Path & operator/=(const Path &path)
add to end of path with path separator
Definition: Path.h:161
Path & append(const Path &path)
add to end of path with path separator
Path & concat(char c)
directly add to end of path without a path separator
Definition: Path.h:148
Path & concat(const Path &path)
directly add to end of path without a path separator
Definition: Path.h:141
Path & operator+=(const Path &path)
directly add to end of path without a path separator
Definition: Path.h:155