Consolix
Loading...
Searching...
No Matches
std_compat.hpp
Go to the documentation of this file.
1#pragma once
2#ifndef _CONSOLIX_STD_COMPAT_HPP_INCLUDED
3#define _CONSOLIX_STD_COMPAT_HPP_INCLUDED
4
7
8#include <mutex>
9#include <system_error>
10
11#if __cplusplus >= 201703L
12#include <filesystem>
13#include <shared_mutex>
14#elif __cplusplus >= 201402L
15#include <experimental/filesystem>
16#include <shared_mutex>
17#else
18#include <experimental/filesystem>
19#endif
20
21namespace consolix {
22namespace compat {
23
24#if __cplusplus >= 201703L
25
26 namespace filesystem = std::filesystem;
27 using shared_mutex = std::shared_mutex;
28
29 template <typename Mutex>
30 using shared_lock = std::shared_lock<Mutex>;
31
32 inline filesystem::path relative(
33 const filesystem::path& path,
34 const filesystem::path& base,
35 std::error_code& ec) {
36 return filesystem::relative(path, base, ec);
37 }
38
39#elif __cplusplus >= 201402L
40
41 namespace filesystem = std::experimental::filesystem;
42 using shared_mutex = std::shared_timed_mutex;
43
44 template <typename Mutex>
45 using shared_lock = std::shared_lock<Mutex>;
46
47 inline filesystem::path relative(
48 const filesystem::path& path,
49 const filesystem::path& base,
50 std::error_code& ec) {
51 ec.clear();
52
53 try {
54 const filesystem::path absolute_path = filesystem::absolute(path);
55 const filesystem::path absolute_base = filesystem::absolute(base);
56
57 auto path_it = absolute_path.begin();
58 auto base_it = absolute_base.begin();
59
60 while (path_it != absolute_path.end() && base_it != absolute_base.end() && *path_it == *base_it) {
61 ++path_it;
62 ++base_it;
63 }
64
65 filesystem::path result;
66 for (; base_it != absolute_base.end(); ++base_it) {
67 result /= "..";
68 }
69 for (; path_it != absolute_path.end(); ++path_it) {
70 result /= *path_it;
71 }
72
73 if (result.empty()) {
74 result = ".";
75 }
76
77 return result;
78 } catch (const filesystem::filesystem_error& error) {
79 ec = error.code();
80 return filesystem::path();
81 }
82 }
83
84#else
85
86 namespace filesystem = std::experimental::filesystem;
87
89 public:
90 void lock() {
91 m_mutex.lock();
92 }
93
94 void unlock() {
95 m_mutex.unlock();
96 }
97
98 bool try_lock() {
99 return m_mutex.try_lock();
100 }
101
102 void lock_shared() {
103 m_mutex.lock();
104 }
105
107 m_mutex.unlock();
108 }
109
111 return m_mutex.try_lock();
112 }
113
114 private:
115 std::mutex m_mutex;
116 };
117
118 template <typename Mutex>
119 using shared_lock = std::unique_lock<Mutex>;
120
121 inline filesystem::path relative(
122 const filesystem::path& path,
123 const filesystem::path& base,
124 std::error_code& ec) {
125 ec.clear();
126
127 try {
128 const filesystem::path absolute_path = filesystem::absolute(path);
129 const filesystem::path absolute_base = filesystem::absolute(base);
130
131 auto path_it = absolute_path.begin();
132 auto base_it = absolute_base.begin();
133
134 while (path_it != absolute_path.end() && base_it != absolute_base.end() && *path_it == *base_it) {
135 ++path_it;
136 ++base_it;
137 }
138
139 filesystem::path result;
140 for (; base_it != absolute_base.end(); ++base_it) {
141 result /= "..";
142 }
143 for (; path_it != absolute_path.end(); ++path_it) {
144 result /= *path_it;
145 }
146
147 if (result.empty()) {
148 result = ".";
149 }
150
151 return result;
152 } catch (const filesystem::filesystem_error& error) {
153 ec = error.code();
154 return filesystem::path();
155 }
156 }
157
158#endif
159
160} // namespace compat
161} // namespace consolix
162
163#endif // _CONSOLIX_STD_COMPAT_HPP_INCLUDED
std::unique_lock< Mutex > shared_lock
filesystem::path relative(const filesystem::path &path, const filesystem::path &base, std::error_code &ec)
< Utility modules and helpers.