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
12namespace 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 const auto& el = mapping[m];
136 if (to < el.to) {
137 l = 0;
138 r = m;
139 }
140 else if (el.to < to) {
141 if (mapping.size() - 1 <= m || to < mapping[m + 1].to)
142 return el.from + (to - el.to);
143 l = m + 1;
144 r = mapping.size();
145 }
146 else
147 return el.from;
148
149 for (;;) {
150 if (l < r) {
151 m = (l + r) / 2;
152 const auto& el = mapping[m];
153 if (to < el.to) r = m;
154 else if (el.to < to) l = m + 1;
155 else return el.from;
156 }
157 else if (l) {
158 const auto& el = mapping[m = l - 1];
159 return el.from + (to - el.to);
160 }
161 else {
162 const auto& el = mapping[m = 0];
163 return std::min<T>(to, el.from);
164 }
165 }
166 }
167
176 template <class T, class AX = std::allocator<mapping<T>>>
177 T src2dst(_In_ const std::vector<stdex::mapping<T>, AX>& mapping, _In_ T from)
178 {
179 if (mapping.empty())
180 return from;
181
182 for (size_t l = 0, r = mapping.size();;) {
183 if (l < r) {
184 auto m = (l + r) / 2;
185 const auto& el = mapping[m];
186 if (from < el.from) r = m;
187 else if (el.from < from) l = m + 1;
188 else return el.to;
189 }
190 else if (l) {
191 const auto& el = mapping[l - 1];
192 return el.to + (from - el.from);
193 }
194 else {
195 const auto& el = mapping[0];
196 return std::min<T>(from, el.to);
197 }
198 }
199 }
200
210 template <class T, class AX = std::allocator<mapping<T>>>
211 T src2dst(_In_ const std::vector<stdex::mapping<T>, AX>& mapping, _In_ T from, _Inout_opt_ size_t& m)
212 {
213 if (mapping.empty())
214 return from;
215
216 size_t l, r;
217 const auto& el = mapping[m];
218 if (from < el.from) {
219 l = 0;
220 r = m;
221 }
222 else if (el.from < from) {
223 if (mapping.size() - 1 <= m || from < mapping[m + 1].from)
224 return el.to + (from - el.from);
225 l = m + 1;
226 r = mapping.size();
227 }
228 else
229 return el.to;
230
231 for (;;) {
232 if (l < r) {
233 m = (l + r) / 2;
234 const auto& el = mapping[m];
235 if (from < el.from) r = m;
236 else if (el.from < from) l = m + 1;
237 else return el.to;
238 }
239 else if (l) {
240 const auto& el = mapping[m = l - 1];
241 return el.to + (from - el.from);
242 }
243 else {
244 const auto& el = mapping[m = 0];
245 return std::min<T>(from, el.to);
246 }
247 }
248 }
249}
Maps index in source string to index in destination string.
Definition mapping.hpp:18
mapping(T x)
Constructs an id mapping.
Definition mapping.hpp:32
bool operator==(const mapping &other) const
Are mappings identical?
Definition mapping.hpp:49
mapping()
Constructs a zero to zero mapping.
Definition mapping.hpp:25
bool operator!=(const mapping &other) const
Are mappings different?
Definition mapping.hpp:58
mapping operator+(const mapping &other) const
Adds two mappings by components.
Definition mapping.hpp:67
mapping(T _from, T _to)
Constructs a mapping.
Definition mapping.hpp:40
void invert()
Reverses source and destination indexes.
Definition mapping.hpp:75