1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
/* Copyright (c) 2020, Dyssol Development Team. All rights reserved. This file is part of Dyssol. See LICENSE file for license information. */
#include "TwoWayMap.h"
#include "ContainerFunctions.h"
#include <numeric>
void CTwoWayMap::Set(double _left, double _right)
{
if (m_direct.HasParam(_left) || m_revert.HasParam(_right)) return;
m_direct.SetValue(_left, _right);
m_revert.SetValue(_right, _left);
}
void CTwoWayMap::SetLeftToRight(const CDependentValues& _table)
{
m_direct = Unique(_table);
m_revert = Reverted(m_direct);
}
void CTwoWayMap::SetRightToLeft(const CDependentValues& _table)
{
m_revert = Unique(_table);
m_direct = Reverted(m_revert);
}
void CTwoWayMap::Remove(double _left, double _right)
{
if (!m_direct.HasParam(_left) || m_direct.GetValue(_left) != _right) return;
m_direct.RemoveValue(_left);
m_revert.RemoveValue(_right);
}
void CTwoWayMap::RemoveLeft(double _left)
{
if (!m_direct.HasParam(_left)) return;
m_revert.RemoveValue(m_direct.GetValue(_left));
m_direct.RemoveValue(_left);
}
void CTwoWayMap::RemoveRight(double _right)
{
if (!m_revert.HasParam(_right)) return;
m_direct.RemoveValue(m_revert.GetValue(_right));
m_revert.RemoveValue(_right);
}
double CTwoWayMap::GetLeft(double _right) const
{
return m_revert.GetValue(_right);
}
double CTwoWayMap::GetRight(double _left) const
{
return m_direct.GetValue(_left);
}
bool CTwoWayMap::HasLeft(double _left) const
{
return m_direct.HasParam(_left);
}
bool CTwoWayMap::HasRight(double _right) const
{
return m_revert.HasParam(_right);
}
const CDependentValues& CTwoWayMap::GetLeftToRightTable() const
{
return m_direct;
}
const CDependentValues& CTwoWayMap::GetRightToLeftTable() const
{
return m_revert;
}
size_t CTwoWayMap::Size() const
{
return m_direct.Size();
}
bool CTwoWayMap::IsEmpty() const
{
return m_direct.IsEmpty();
}
void CTwoWayMap::Clear()
{
m_direct.Clear();
m_revert.Clear();
}
bool CTwoWayMap::operator==(const CTwoWayMap& _other) const
{
return m_direct == _other.m_direct && m_revert == _other.m_revert;
}
CDependentValues CTwoWayMap::Reverted(const CDependentValues& _table)
{
return CDependentValues{ _table.GetValuesList(), _table.GetParamsList() };
}
CDependentValues CTwoWayMap::Unique(const CDependentValues& _table)
{
const auto& params = _table.GetParamsList();
const auto& values = _table.GetValuesList();
// initial index locations
std::vector<size_t> iparams(params.size());
std::vector<size_t> ivalues(values.size());
std::iota(iparams.begin(), iparams.end(), 0);
std::iota(ivalues.begin(), ivalues.end(), 0);
// sort indices based on comparing data in vectors
std::stable_sort(iparams.begin(), iparams.end(), [&](size_t i1, size_t i2) { return params[i1] < params[i2]; });
std::stable_sort(ivalues.begin(), ivalues.end(), [&](size_t i1, size_t i2) { return values[i1] < values[i2]; });
// indices of elements to be deleted
std::set<size_t> todel;
// find all but first repeating params
for (size_t i = 1; i < iparams.size(); ++i)
if (params[iparams[i]] == params[iparams[i - 1]])
todel.insert(iparams[i]);
// find all but first repeating values
for (size_t i = 1; i < ivalues.size(); ++i)
if (values[ivalues[i]] == values[ivalues[i - 1]])
todel.insert(ivalues[i]);
if (!todel.empty())
{
// create a copy of the table
CDependentValues res = _table;
// remove not unique
for (const auto& i : todel)
res.RemoveValue(params[i]);
return res;
}
else
return _table;
}
|