# stdex: include/stdex/mapping.hpp Source File

Loading...
Searching...
No Matches
mapping.hpp
/*
SPDX-License-Identifier: MIT
Copyright © 2023-2024 Amebis
*/
#pragma once
#include "compat.hpp"
#include <algorithm>
#include <vector>
namespace stdex
{
template <class T>
struct mapping {
T from; // index in source string
T to; // index in destination string
mapping() : from(0), to(0) {}
mapping(_In_ T x) : from(x), to(x) {}
mapping(_In_ T _from, _In_ T _to) : from(_from), to(_to) {}
bool operator==(const mapping& other) const { return from == other.from && to == other.to; }
bool operator!=(const mapping& other) const { return !operator==(other); }
mapping operator+(_In_ const mapping& other) const
{
return mapping(from + other.from, to + other.to);
}
void invert()
{
T tmp = from;
from = to;
to = tmp;
}
};
template <class T, class AX = std::allocator<mapping<T>>>
using mapping_vector = std::vector<mapping<T>, AX>;
template <class T, class AX = std::allocator<mapping<T>>>
T dst2src(_In_ const std::vector<stdex::mapping<T>, AX>& mapping, _In_ T to)
{
if (mapping.empty())
return to;
for (size_t l = 0, r = mapping.size();;) {
if (l < r) {
auto m = (l + r) / 2;
const auto& el = mapping[m];
if (to < el.to) r = m;
else if (el.to < to) l = m + 1;
else return el.from;
}
else if (l) {
const auto& el = mapping[l - 1];
return el.from + (to - el.to);
}
else {
const auto& el = mapping[0];
return std::min<T>(to, el.from);
}
}
}
template <class T, class AX = std::allocator<mapping<T>>>
T dst2src(_In_ const std::vector<stdex::mapping<T>, AX>& mapping, _In_ T to, _Inout_opt_ size_t& m)
{
if (mapping.empty())
return to;
size_t l, r;
{
const auto& el = mapping[m];
if (to < el.to) {
l = 0;
r = m;
}
else if (el.to < to) {
if (mapping.size() - 1 <= m || to < mapping[m + 1].to)
return el.from + (to - el.to);
l = m + 1;
r = mapping.size();
}
else
return el.from;
}
for (;;) {
if (l < r) {
m = (l + r) / 2;
const auto& el = mapping[m];
if (to < el.to) r = m;
else if (el.to < to) l = m + 1;
else return el.from;
}
else if (l) {
const auto& el = mapping[m = l - 1];
return el.from + (to - el.to);
}
else {
const auto& el = mapping[m = 0];
return std::min<T>(to, el.from);
}
}
}
template <class T, class AX = std::allocator<mapping<T>>>
T src2dst(_In_ const std::vector<stdex::mapping<T>, AX>& mapping, _In_ T from)
{
if (mapping.empty())
return from;
for (size_t l = 0, r = mapping.size();;) {
if (l < r) {
auto m = (l + r) / 2;
const auto& el = mapping[m];
if (from < el.from) r = m;
else if (el.from < from) l = m + 1;
else return el.to;
}
else if (l) {
const auto& el = mapping[l - 1];
return el.to + (from - el.from);
}
else {
const auto& el = mapping[0];
return std::min<T>(from, el.to);
}
}
}
template <class T, class AX = std::allocator<mapping<T>>>
T src2dst(_In_ const std::vector<stdex::mapping<T>, AX>& mapping, _In_ T from, _Inout_opt_ size_t& m)
{
if (mapping.empty())
return from;
size_t l, r;
{
const auto& el = mapping[m];
if (from < el.from) {
l = 0;
r = m;
}
else if (el.from < from) {
if (mapping.size() - 1 <= m || from < mapping[m + 1].from)
return el.to + (from - el.from);
l = m + 1;
r = mapping.size();
}
else
return el.to;
}
for (;;) {
if (l < r) {
m = (l + r) / 2;
const auto& el = mapping[m];
if (from < el.from) r = m;
else if (el.from < from) l = m + 1;
else return el.to;
}
else if (l) {
const auto& el = mapping[m = l - 1];
return el.to + (from - el.from);
}
else {
const auto& el = mapping[m = 0];
return std::min<T>(from, el.to);
}
}
}
}
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