Iros
 
Loading...
Searching...
No Matches
constant_path_interface.h
Go to the documentation of this file.
1#pragma once
2
10
11namespace di::container {
12template<concepts::Encoding Enc>
13class PathViewImpl;
14
15template<typename Self, concepts::Encoding Enc>
17private:
18 using View = string::StringViewImpl<Enc>;
19 using CodePoint = meta::EncodingCodePoint<Enc>;
20 using ViewIter = meta::ContainerIterator<View>;
21 using PathView = PathViewImpl<Enc>;
22
23 constexpr auto self() -> Self& { return static_cast<Self&>(*this); }
24 constexpr auto self() const -> Self const& { return static_cast<Self const&>(*this); }
25
26 constexpr auto data() const -> View { return self().data(); }
27
28public:
29 constexpr auto empty() const -> bool { return data().empty(); }
30
31 constexpr auto view() const& -> PathView { return PathView(data()); }
32 constexpr operator PathView() const& { return view(); }
33
34 constexpr auto front() const {
35 return lift_bool(!empty()) % [&] {
36 return *begin();
37 };
38 }
39 constexpr auto back() const {
40 return lift_bool(!empty()) % [&] {
41 return *--end();
42 };
43 }
44
45 constexpr auto begin() const { return PathIterator(data(), { data().begin(), m_first_component_end }); }
46 constexpr auto end() const { return PathIterator(data(), { data().end(), data().end() }); }
47
48 constexpr auto is_absolute() const -> bool { return data().starts_with(CodePoint('/')); }
49 constexpr auto is_relative() const -> bool { return !is_absolute(); }
50
51 constexpr auto filename() const -> Optional<View> {
52 return lift_bool(!empty() && !data().ends_with(CodePoint('/'))) % [&] {
53 auto trailing_slash = data().rfind(CodePoint('/'));
54 if (!trailing_slash) {
55 return data();
56 }
57 return data().substr(trailing_slash.end());
58 };
59 }
60
61 constexpr auto extension() const -> Optional<View> {
62 auto filename = this->filename();
63 if (!filename) {
64 return nullopt;
65 }
66 auto split = split_filename(*filename);
67 return util::get<1>(split);
68 }
69
70 constexpr auto stem() const -> Optional<View> {
71 auto filename = this->filename();
72 if (!filename) {
73 return nullopt;
74 }
75 auto split = split_filename(*filename);
76 return util::get<0>(split);
77 }
78
79 constexpr auto parent_path() const -> Optional<PathView> {
80 return lift_bool(!empty() && !container::all_of(data(), function::equal(CodePoint('/')))) >> [&] {
81 auto result = PathView(strip_filename(data()));
82 return lift_bool(!result.empty()) % [&] {
83 return result;
84 };
85 };
86 }
87
88 constexpr auto starts_with(PathView prefix) const -> bool { return container::starts_with(*this, prefix); }
89 constexpr auto ends_with(PathView suffix) const -> bool { return container::ends_with(*this, suffix); }
90
91 constexpr auto filename_ends_with(View suffix) const -> bool {
92 return filename() % [&](auto filename) {
93 return filename.ends_with(suffix);
94 } == true;
95 }
96
97 constexpr auto strip_prefix(PathView prefix) -> Optional<PathView> {
98 auto [a, b] = container::mismatch(*this, prefix);
99 if (b != prefix.end()) {
100 return nullopt;
101 }
102 return PathView(View(a.current_data(), this->end().current_data()));
103 }
104
105protected:
107 if (data().starts_with(CodePoint('/'))) {
108 m_first_component_end = container::next(data().begin());
109 } else {
110 m_first_component_end = container::find(data(), CodePoint('/'));
111 }
112 }
113
114private:
115 constexpr friend auto operator==(Self const& a, Self const& b) -> bool { return container::equal(a, b); }
116 constexpr friend auto operator<=>(Self const& a, Self const& b) { return container::compare(a, b); }
117
118 constexpr static auto split_filename(View filename) -> Tuple<Optional<View>, Optional<View>> {
119 auto last_dot_view = filename.rfind(CodePoint('.'));
120 if (!last_dot_view || last_dot_view.begin() == filename.begin()) {
121 return { filename, nullopt };
122 }
123 return { filename.substr(filename.begin(), last_dot_view.begin()), filename.substr(last_dot_view.end()) };
124 }
125
126 constexpr static auto strip_filename(View view) -> View {
127 while (view.ends_with(CodePoint('/'))) {
128 view.replace_end(container::prev(view.end()));
129 }
130 while (!view.empty() && !view.ends_with(CodePoint('/'))) {
131 view.replace_end(container::prev(view.end()));
132 }
133 while (view.size() > 2 && view.ends_with(CodePoint('/'))) {
134 view.replace_end(container::prev(view.end()));
135 }
136 return view;
137 }
138
139 ViewIter m_first_component_end {};
140};
141}
Definition constant_path_interface.h:16
constexpr auto starts_with(PathView prefix) const -> bool
Definition constant_path_interface.h:88
constexpr auto filename_ends_with(View suffix) const -> bool
Definition constant_path_interface.h:91
constexpr auto front() const
Definition constant_path_interface.h:34
constexpr auto filename() const -> Optional< View >
Definition constant_path_interface.h:51
constexpr auto extension() const -> Optional< View >
Definition constant_path_interface.h:61
constexpr auto is_absolute() const -> bool
Definition constant_path_interface.h:48
constexpr auto begin() const
Definition constant_path_interface.h:45
constexpr auto back() const
Definition constant_path_interface.h:39
constexpr auto view() const &-> PathView
Definition constant_path_interface.h:31
constexpr auto stem() const -> Optional< View >
Definition constant_path_interface.h:70
constexpr void compute_first_component_end()
Definition constant_path_interface.h:106
constexpr auto is_relative() const -> bool
Definition constant_path_interface.h:49
constexpr auto ends_with(PathView suffix) const -> bool
Definition constant_path_interface.h:89
constexpr friend auto operator<=>(Self const &a, Self const &b)
Definition constant_path_interface.h:116
constexpr auto strip_prefix(PathView prefix) -> Optional< PathView >
Definition constant_path_interface.h:97
constexpr auto empty() const -> bool
Definition constant_path_interface.h:29
constexpr auto parent_path() const -> Optional< PathView >
Definition constant_path_interface.h:79
constexpr auto end() const
Definition constant_path_interface.h:46
constexpr friend auto operator==(Self const &a, Self const &b) -> bool
Definition constant_path_interface.h:115
Definition path_iterator.h:17
Definition path_view_impl.h:22
Definition view.h:35
Definition string_view_impl_forward_declaration.h:7
Definition optional_forward_declaration.h:5
Definition tuple_forward_declaration.h:5
Definition sequence.h:12
constexpr auto prev
Definition prev.h:28
constexpr auto next
Definition next.h:35
constexpr auto find
Definition find.h:35
constexpr auto starts_with
Definition starts_with.h:30
constexpr auto ends_with
Definition ends_with.h:41
constexpr auto mismatch
Definition mismatch.h:40
constexpr auto equal
Definition equal.h:46
constexpr auto compare
Definition compare.h:40
constexpr auto all_of
Definition all_of.h:24
constexpr auto equal
Definition equal.h:23
RemoveCVRef< T >::CodePoint EncodingCodePoint
Definition encoding.h:19
decltype(container::begin(util::declval< T & >())) ContainerIterator
Definition container_iterator.h:8
constexpr auto get(T &&value) -> decltype(auto)
Definition get.h:8
constexpr auto nullopt
Definition nullopt.h:15
constexpr auto lift_bool
Definition lift_bool.h:13