File: TwoWayMap.cpp

package info (click to toggle)
dyssol 1.5.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 18,184 kB
  • sloc: cpp: 53,870; sh: 85; python: 59; makefile: 11
file content (136 lines) | stat: -rw-r--r-- 3,468 bytes parent folder | download | duplicates (3)
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;
}