Silicium
absolute_path.hpp
Go to the documentation of this file.
1 #ifndef SILICIUM_ABSOLUTE_PATH_HPP
2 #define SILICIUM_ABSOLUTE_PATH_HPP
3 
5 #include <silicium/optional.hpp>
6 #include <silicium/error_or.hpp>
7 #include <silicium/is_handle.hpp>
8 #include <silicium/c_string.hpp>
9 
10 //Boost filesystem requires exceptions
11 #define SILICIUM_HAS_ABSOLUTE_PATH_OPERATIONS SILICIUM_HAS_EXCEPTIONS
12 
13 #if SILICIUM_HAS_ABSOLUTE_PATH_OPERATIONS
14 # include <boost/filesystem/operations.hpp>
15 #endif
16 
17 #include <iostream>
18 
19 namespace Si
20 {
22  {
25 
26  absolute_path() BOOST_NOEXCEPT
27  {
28  }
29 
30  absolute_path(absolute_path &&other) BOOST_NOEXCEPT
31  : m_value(std::move(other.m_value))
32  {
33  }
34 
36  : m_value(other.m_value)
37  {
38  }
39 
40  absolute_path &operator = (absolute_path &&other) BOOST_NOEXCEPT
41  {
42  m_value = std::move(other.m_value);
43  return *this;
44  }
45 
47  {
48  m_value = other.m_value;
49  return *this;
50  }
51 
52  void swap(absolute_path &other) BOOST_NOEXCEPT
53  {
54  m_value.swap(other.m_value);
55  }
56 
58  boost::filesystem::path
59 #ifdef _WIN32
60  const &
61 #endif
62  to_boost_path() const
63  {
64  return m_value.to_boost_path();
65  }
66 
68 #ifdef _WIN32
69  boost::filesystem::path const &
70 #else
71  noexcept_string const &
72 #endif
73  underlying() const BOOST_NOEXCEPT
74  {
75  return m_value.underlying();
76  }
77 
79  char_type const *c_str() const BOOST_NOEXCEPT
80  {
81  return m_value.c_str();
82  }
83 
85  native_path_string safe_c_str() const BOOST_NOEXCEPT
86  {
87  return native_path_string(c_str());
88  }
89 
90  void combine(relative_path const &back)
91  {
92  //TODO: optimize
93  *this = absolute_path(to_boost_path() / back.to_boost_path());
94  }
95 
97  bool empty() const BOOST_NOEXCEPT
98  {
99  return underlying().empty();
100  }
101 
103  static optional<absolute_path> create(boost::filesystem::path const &maybe_absolute)
104  {
105  if (maybe_absolute.is_absolute())
106  {
107  return absolute_path(maybe_absolute);
108  }
109  return none;
110  }
111 
113  static optional<absolute_path> create(noexcept_string const &maybe_absolute)
114  {
115  return create(boost::filesystem::path(maybe_absolute.c_str()));
116  }
117 
119  static optional<absolute_path> create(char const *maybe_absolute)
120  {
121  return create(boost::filesystem::path(maybe_absolute));
122  }
123 
124 #ifdef _WIN32
126  static optional<absolute_path> create(wchar_t const *maybe_absolute)
127  {
128  return create(boost::filesystem::path(maybe_absolute));
129  }
130 #endif
131 
132  private:
133 
134  path m_value;
135 
136  explicit absolute_path(boost::filesystem::path const &value)
137  : m_value(value)
138  {
139  }
140  };
141 
143 
144  inline std::ostream &operator << (std::ostream &out, absolute_path const &p)
145  {
146  return out << p.underlying();
147  }
148 
149  inline std::istream &operator >> (std::istream &in, absolute_path &p)
150  {
152  in >> temp;
153  if (!in)
154  {
155  return in;
156  }
158  if (!checked)
159  {
160  in.setstate(std::ios::failbit);
161  return in;
162  }
163  p = std::move(*checked);
164  return in;
165  }
166 
167  template <class ComparableToPath>
169  inline bool operator == (absolute_path const &left, ComparableToPath const &right)
170  {
171  return left.underlying() == right;
172  }
173 
174  template <class ComparableToPath>
176  inline bool operator == (ComparableToPath const &left, absolute_path const &right)
177  {
178  return left == right.underlying();
179  }
180 
182  inline bool operator == (absolute_path const &left, boost::filesystem::path const &right)
183  {
184  return right == left.c_str();
185  }
186 
188  inline bool operator == (boost::filesystem::path const &left, absolute_path const &right)
189  {
190  return left == right.c_str();
191  }
192 
194  inline bool operator == (absolute_path const &left, absolute_path const &right)
195  {
196  return left.underlying() == right.underlying();
197  }
198 
199  template <class ComparableToPath>
201  inline bool operator != (absolute_path const &left, ComparableToPath const &right)
202  {
203  return !(left == right);
204  }
205 
206  template <class ComparableToPath>
208  inline bool operator != (ComparableToPath const &left, absolute_path const &right)
209  {
210  return !(left == right);
211  }
212 
214  inline bool operator < (absolute_path const &left, absolute_path const &right)
215  {
216  return left.underlying() < right.underlying();
217  }
218 
220  inline std::size_t hash_value(absolute_path const &value)
221  {
222  using boost::hash_value;
223  return hash_value(value.underlying());
224  }
225 
227  inline relative_path leaf(absolute_path const &whole)
228  {
229  //TODO: do this efficiently
230  return relative_path(whole.to_boost_path().leaf());
231  }
232 
235  {
236  //TODO: do this efficiently
237  auto boosted = whole.to_boost_path();
238  if (boosted.has_parent_path())
239  {
240  return *absolute_path::create(boosted.parent_path());
241  }
242  return none;
243  }
244 
246  inline absolute_path operator / (absolute_path const &front, relative_path const &back)
247  {
248  //TODO: do this efficiently
249  absolute_path result = front;
250  result.combine(back);
251  return result;
252  }
253 
254  template <std::size_t N>
256  inline absolute_path operator / (absolute_path const &front, absolute_path::char_type const (&literal)[N])
257  {
258  return front / relative_path(boost::filesystem::path(&literal[0]));
259  }
260 
261 #ifdef _WIN32
262  template <std::size_t N>
264  inline absolute_path operator / (absolute_path const &front, char const (&literal)[N])
265  {
266  return front / relative_path(boost::filesystem::path(&literal[0]));
267  }
268 #endif
269 
270 #if SILICIUM_HAS_ABSOLUTE_PATH_OPERATIONS
273  {
274  return *absolute_path::create(boost::filesystem::current_path());
275  }
276 
278  inline boost::system::error_code remove_file(absolute_path const &name)
279  {
280  boost::system::error_code ec;
281  boost::filesystem::remove(name.to_boost_path(), ec);
282  return ec;
283  }
284 
286  inline boost::system::error_code create_directories(absolute_path const &directories)
287  {
288  boost::system::error_code ec;
290  return ec;
291  }
292 
295  {
296  boost::system::error_code ec;
297  auto count = boost::filesystem::remove_all(directories.to_boost_path(), ec);
298  if (!!ec)
299  {
300  return ec;
301  }
302  return count;
303  }
304 
306  inline boost::system::error_code recreate_directories(absolute_path const &directories)
307  {
308  boost::system::error_code error = create_directories(directories);
309  if (!!error)
310  {
311  return error;
312  }
313  boost::filesystem::directory_iterator i(directories.to_boost_path(), error);
314  if (!!error)
315  {
316  return error;
317  }
318  for (; i != boost::filesystem::directory_iterator{}; )
319  {
320  boost::filesystem::remove_all(i->path(), error);
321  if (!!error)
322  {
323  return error;
324  }
325  i.increment(error);
326  if (!!error)
327  {
328  return error;
329  }
330  }
331  return error;
332  }
333 
336  {
337  boost::system::error_code ec;
338  boost::filesystem::file_status status = boost::filesystem::status(file.to_boost_path(), ec);
339  if (status.type() == boost::filesystem::file_not_found)
340  {
341  return false;
342  }
343  if (ec)
344  {
345  return ec;
346  }
347  return true;
348  }
349 #endif
350 }
351 
352 namespace std
353 {
354  template <>
355  struct hash< ::Si::absolute_path>
356  {
358  std::size_t operator()(Si::absolute_path const &value) const
359  {
360  return hash_value(value);
361  }
362  };
363 }
364 
365 #endif
Definition: c_string.hpp:10
static SILICIUM_USE_RESULT optional< absolute_path > create(noexcept_string const &maybe_absolute)
Definition: absolute_path.hpp:113
SILICIUM_USE_RESULT bool empty() const BOOST_NOEXCEPT
Definition: absolute_path.hpp:97
SILICIUM_USE_RESULT optional< absolute_path > parent(absolute_path const &whole)
Definition: absolute_path.hpp:234
std::remove_reference< T >::type && move(T &&ref)
Definition: move.hpp:10
SILICIUM_USE_RESULT boost::system::error_code remove_file(absolute_path const &name)
Definition: absolute_path.hpp:278
Definition: absolute_path.hpp:21
SILICIUM_USE_RESULT error_or< bool > file_exists(absolute_path const &file)
Definition: absolute_path.hpp:335
SILICIUM_USE_RESULT boost::system::error_code create_directories(absolute_path const &directories)
Definition: absolute_path.hpp:286
SILICIUM_USE_RESULT relative_path leaf(absolute_path const &whole)
Definition: absolute_path.hpp:227
BOOST_STATIC_ASSERT(Si::is_handle< absolute_path >::value)
std::ostream & operator<<(std::ostream &out, absolute_path const &p)
Definition: absolute_path.hpp:144
void swap(absolute_path &other) BOOST_NOEXCEPT
Definition: absolute_path.hpp:52
char_type const * c_str() const BOOST_NOEXCEPT
Definition: path.hpp:129
std::istream & operator>>(std::istream &in, absolute_path &p)
Definition: absolute_path.hpp:149
Definition: absolute_path.hpp:352
Definition: absolute_path.hpp:19
absolute_path & operator=(absolute_path &&other) BOOST_NOEXCEPT
Definition: absolute_path.hpp:40
Definition: optional.hpp:39
boost::container::string noexcept_string
Definition: noexcept_string.hpp:26
static SILICIUM_USE_RESULT optional< absolute_path > create(char const *maybe_absolute)
Definition: absolute_path.hpp:119
noexcept_string const & underlying() const BOOST_NOEXCEPT
Definition: path.hpp:124
SILICIUM_USE_RESULT boost::filesystem::path to_boost_path() const
Definition: absolute_path.hpp:62
boost::filesystem::path to_boost_path() const
Definition: path.hpp:110
path::underlying_type underlying_type
Definition: absolute_path.hpp:24
SILICIUM_USE_RESULT absolute_path operator/(absolute_path const &front, relative_path const &back)
Definition: absolute_path.hpp:246
SILICIUM_USE_RESULT bool operator==(absolute_path const &left, ComparableToPath const &right)
Definition: absolute_path.hpp:169
SILICIUM_USE_RESULT char_type const * c_str() const BOOST_NOEXCEPT
Definition: absolute_path.hpp:79
static SILICIUM_USE_RESULT optional< absolute_path > create(boost::filesystem::path const &maybe_absolute)
Definition: absolute_path.hpp:103
SILICIUM_USE_RESULT bool operator<(absolute_path const &left, absolute_path const &right)
Definition: absolute_path.hpp:214
os_c_string native_path_string
Definition: c_string.hpp:70
absolute_path(absolute_path const &other)
Definition: absolute_path.hpp:35
noexcept_string underlying_type
Definition: path.hpp:20
absolute_path() BOOST_NOEXCEPT
Definition: absolute_path.hpp:26
SILICIUM_USE_RESULT boost::system::error_code recreate_directories(absolute_path const &directories)
Definition: absolute_path.hpp:306
SILICIUM_USE_RESULT boost::filesystem::path to_boost_path() const
Definition: relative_path.hpp:94
void combine(relative_path const &back)
Definition: absolute_path.hpp:90
SILICIUM_USE_RESULT absolute_path get_current_working_directory()
Definition: absolute_path.hpp:272
Definition: error_or.hpp:48
SILICIUM_USE_RESULT native_path_string safe_c_str() const BOOST_NOEXCEPT
Definition: absolute_path.hpp:85
SILICIUM_USE_RESULT noexcept_string const & underlying() const BOOST_NOEXCEPT
Definition: absolute_path.hpp:73
native_path_char char_type
Definition: absolute_path.hpp:23
Definition: is_handle.hpp:21
SILICIUM_USE_RESULT std::size_t hash_value(absolute_path const &value)
Definition: absolute_path.hpp:220
SILICIUM_USE_RESULT bool operator!=(absolute_path const &left, ComparableToPath const &right)
Definition: absolute_path.hpp:201
char native_path_char
Definition: path_char.hpp:14
SILICIUM_USE_RESULT error_or< boost::uint64_t > remove_all(absolute_path const &directories)
Definition: absolute_path.hpp:294
void swap(path &other) BOOST_NOEXCEPT
Definition: path.hpp:101
Definition: relative_path.hpp:10
SILICIUM_USE_RESULT std::size_t operator()(Si::absolute_path const &value) const
Definition: absolute_path.hpp:358
absolute_path(absolute_path &&other) BOOST_NOEXCEPT
Definition: absolute_path.hpp:30
#define SILICIUM_USE_RESULT
Definition: config.hpp:147