stdex Additional custom or not Standard C++ covered algorithms

Loading...
Searching...
No Matches
mapping.hpp
1/*
2 SPDX-License-Identifier: MIT
3 Copyright © 2023-2024 Amebis
4*/
5
6#pragma once
7
8#include "compat.hpp"
9#include <algorithm>
10#include <vector>
11
12 namespace stdex
13{
17 template <class T>
18 struct mapping {
19 T from; // index in source string
20 T to; // index in destination string
21
25 mapping() : from(0), to(0) {}
26
32 mapping(_In_ T x) : from(x), to(x) {}
33
40 mapping(_In_ T _from, _In_ T _to) : from(_from), to(_to) {}
41
49 bool operator==(const mapping& other) const { return from == other.from && to == other.to; }
50
58 bool operator!=(const mapping& other) const { return !operator==(other); }
59
67 mapping operator+(_In_ const mapping& other) const
68 {
69 return mapping(from + other.from, to + other.to);
70 }
71
75 void invert()
76 {
77 T tmp = from;
78 from = to;
79 to = tmp;
80 }
81 };
82
83 template <class T, class AX = std::allocator<mapping<T>>>
84 using mapping_vector = std::vector<mapping<T>, AX>;
85
94 template <class T, class AX = std::allocator<mapping<T>>>
95 T dst2src(_In_ const std::vector<stdex::mapping<T>, AX>& mapping, _In_ T to)
96 {
97 if (mapping.empty())
98 return to;
99
100 for (size_t l = 0, r = mapping.size();;) {
101 if (l < r) {
102 auto m = (l + r) / 2;
103 const auto& el = mapping[m];
104 if (to < el.to) r = m;
105 else if (el.to < to) l = m + 1;
106 else return el.from;
107 }
108 else if (l) {
109 const auto& el = mapping[l - 1];
110 return el.from + (to - el.to);
111 }
112 else {
113 const auto& el = mapping[0];
114 return std::min<T>(to, el.from);
115 }
116 }
117 }
118
128 template <class T, class AX = std::allocator<mapping<T>>>
129 T dst2src(_In_ const std::vector<stdex::mapping<T>, AX>& mapping, _In_ T to, _Inout_opt_ size_t& m)
130 {
131 if (mapping.empty())
132 return to;
133
134 size_t l, r;
135 {
136 const auto& el = mapping[m];
137 if (to < el.to) {
138 l = 0;
139 r = m;
140 }
141 else if (el.to < to) {
142 if (mapping.size() - 1 <= m || to < mapping[m + 1].to)
143 return el.from + (to - el.to);
144 l = m + 1;
145 r = mapping.size();
146 }
147 else
148 return el.from;
149 }
150
151 for (;;) {
152 if (l < r) {
153 m = (l + r) / 2;
154 const auto& el = mapping[m];
155 if (to < el.to) r = m;
156 else if (el.to < to) l = m + 1;
157 else return el.from;
158 }
159 else if (l) {
160 const auto& el = mapping[m = l - 1];
161 return el.from + (to - el.to);
162 }
163 else {
164 const auto& el = mapping[m = 0];
165 return std::min<T>(to, el.from);
166 }
167 }
168 }
169
178 template <class T, class AX = std::allocator<mapping<T>>>
179 T src2dst(_In_ const std::vector<stdex::mapping<T>, AX>& mapping, _In_ T from)
180 {
181 if (mapping.empty())
182 return from;
183
184 for (size_t l = 0, r = mapping.size();;) {
185 if (l < r) {
186 auto m = (l + r) / 2;
187 const auto& el = mapping[m];
188 if (from < el.from) r = m;
189 else if (el.from < from) l = m + 1;
190 else return el.to;
191 }
192 else if (l) {
193 const auto& el = mapping[l - 1];
194 return el.to + (from - el.from);
195 }
196 else {
197 const auto& el = mapping[0];
198 return std::min<T>(from, el.to);
199 }
200 }
201 }
202
212 template <class T, class AX = std::allocator<mapping<T>>>
213 T src2dst(_In_ const std::vector<stdex::mapping<T>, AX>& mapping, _In_ T from, _Inout_opt_ size_t& m)
214 {
215 if (mapping.empty())
216 return from;
217
218 size_t l, r;
219 {
220 const auto& el = mapping[m];
221 if (from < el.from) {
222 l = 0;
223 r = m;
224 }
225 else if (el.from < from) {
226 if (mapping.size() - 1 <= m || from < mapping[m + 1].from)
227 return el.to + (from - el.from);
228 l = m + 1;
229 r = mapping.size();
230 }
231 else
232 return el.to;
233 }
234
235 for (;;) {
236 if (l < r) {
237 m = (l + r) / 2;
238 const auto& el = mapping[m];
239 if (from < el.from) r = m;
240 else if (el.from < from) l = m + 1;
241 else return el.to;
242 }
243 else if (l) {
244 const auto& el = mapping[m = l - 1];
245 return el.to + (from - el.from);
246 }
247 else {
248 const auto& el = mapping[m = 0];
249 return std::min<T>(from, el.to);
250 }
251 }
252 }
253}
stdex::mapping
Maps index in source string to index in destination string.
Definition mapping.hpp:18
stdex::mapping::mapping
mapping(T x)
Constructs an id mapping.
Definition mapping.hpp:32
stdex::mapping::operator==
bool operator==(const mapping &other) const
Are mappings identical?
Definition mapping.hpp:49
stdex::mapping::mapping
mapping()
Constructs a zero to zero mapping.
Definition mapping.hpp:25
stdex::mapping::operator!=
bool operator!=(const mapping &other) const
Are mappings different?
Definition mapping.hpp:58
stdex::mapping::operator+
mapping operator+(const mapping &other) const
Adds two mappings by components.
Definition mapping.hpp:67
stdex::mapping::mapping
mapping(T _from, T _to)
Constructs a mapping.
Definition mapping.hpp:40
stdex::mapping::invert
void invert()
Reverses source and destination indexes.
Definition mapping.hpp:75