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 };
72
73 template <class T, class AX = std::allocator<mapping<T>>>
74 using mapping_vector = std::vector<mapping<T>, AX>;
75
84 template <class T, class AX = std::allocator<mapping<T>>>
85 T dst2src(_In_ const std::vector<stdex::mapping<T>, AX>& mapping, _In_ T to)
86 {
87 if (mapping.empty())
88 return to;
89
90 for (size_t l = 0, r = mapping.size();;) {
91 if (l < r) {
92 auto m = (l + r) / 2;
93 const auto& el = mapping[m];
94 if (to < el.to) r = m;
95 else if (el.to < to) l = m + 1;
96 else return el.from;
97 }
98 else if (l) {
99 const auto& el = mapping[l - 1];
100 return el.from + (to - el.to);
101 }
102 else {
103 const auto& el = mapping[0];
104 return std::min<T>(to, el.from);
105 }
106 }
107 }
108
118 template <class T, class AX = std::allocator<mapping<T>>>
119 T dst2src(_In_ const std::vector<stdex::mapping<T>, AX>& mapping, _In_ T to, _Inout_opt_ size_t& m)
120 {
121 if (mapping.empty())
122 return to;
123
124 size_t l, r;
125 const auto& el = mapping[m];
126 if (to < el.to) {
127 l = 0;
128 r = m;
129 }
130 else if (el.to < to) {
131 if (mapping.size() - 1 <= m || to < mapping[m + 1].to)
132 return el.from + (to - el.to);
133 l = m + 1;
134 r = mapping.size();
135 }
136 else
137 return el.from;
138
139 for (;;) {
140 if (l < r) {
141 m = (l + r) / 2;
142 const auto& el = mapping[m];
143 if (to < el.to) r = m;
144 else if (el.to < to) l = m + 1;
145 else return el.from;
146 }
147 else if (l) {
148 const auto& el = mapping[m = l - 1];
149 return el.from + (to - el.to);
150 }
151 else {
152 const auto& el = mapping[m = 0];
153 return std::min<T>(to, el.from);
154 }
155 }
156 }
157
166 template <class T, class AX = std::allocator<mapping<T>>>
167 T src2dst(_In_ const std::vector<stdex::mapping<T>, AX>& mapping, _In_ T from)
168 {
169 if (mapping.empty())
170 return from;
171
172 for (size_t l = 0, r = mapping.size();;) {
173 if (l < r) {
174 auto m = (l + r) / 2;
175 const auto& el = mapping[m];
176 if (from < el.from) r = m;
177 else if (el.from < from) l = m + 1;
178 else return el.to;
179 }
180 else if (l) {
181 const auto& el = mapping[l - 1];
182 return el.to + (from - el.from);
183 }
184 else {
185 const auto& el = mapping[0];
186 return std::min<T>(from, el.to);
187 }
188 }
189 }
190
200 template <class T, class AX = std::allocator<mapping<T>>>
201 T src2dst(_In_ const std::vector<stdex::mapping<T>, AX>& mapping, _In_ T from, _Inout_opt_ size_t& m)
202 {
203 if (mapping.empty())
204 return from;
205
206 size_t l, r;
207 const auto& el = mapping[m];
208 if (from < el.from) {
209 l = 0;
210 r = m;
211 }
212 else if (el.from < from) {
213 if (mapping.size() - 1 <= m || from < mapping[m + 1].from)
214 return el.to + (from - el.from);
215 l = m + 1;
216 r = mapping.size();
217 }
218 else
219 return el.to;
220
221 for (;;) {
222 if (l < r) {
223 m = (l + r) / 2;
224 const auto& el = mapping[m];
225 if (from < el.from) r = m;
226 else if (el.from < from) l = m + 1;
227 else return el.to;
228 }
229 else if (l) {
230 const auto& el = mapping[m = l - 1];
231 return el.to + (from - el.from);
232 }
233 else {
234 const auto& el = mapping[m = 0];
235 return std::min<T>(from, el.to);
236 }
237 }
238 }
239}
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