-
Notifications
You must be signed in to change notification settings - Fork 35
/
Copy pathmultitable.hpp
executable file
·99 lines (91 loc) · 2.83 KB
/
multitable.hpp
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
/** @file */
// Copyright 2012 Yandex Artem Babenko
#pragma once
#include <vector>
using std::vector;
/**
* This class implements interface of multidimensional array with
* fast write/read operations. In fact data is stored in a long array.
* Global index of particular item in this array is calculated from item coordinates.
*/
template<class T>
struct Multitable {
/**
* This constructor gets width of table for each dimension
* @param dimensions array of sizes of table along each dimension
*/
Multitable(const vector<int>& dimensions = vector<int>());
/**
* This function resize the table to new dimensions
* @param dimensions array of sizes of table along each dimension
*/
void Resize(const vector<int>& dimensions, T value = T());
/**
* This function sets value in one cell
* @param value value to set
* @param cell_indices coordinates of cell in the table
*/
void SetValue(T value, const vector<int>& cell_indices);
/**
* This function gets value of one cell
* @param cell_indices coordinates of cell in the table
*/
T GetValue(const vector<int>& cell_indices);
/**
* Actual data as one-dimensional array
*/
vector<T> table;
/**
* Dimensions of table
*/
vector<int> dimensions;
/**
* Function for Boost.Serialization
*/
template<class Archive>
void serialize(Archive& arc, unsigned int version) {
arc & table;
arc & dimensions;
}
/**
* Function converts cell coordinates to global index in a long array
* @param cell_indices coordinates of cell in the table
*/
int GetCellGlobalIndex(const vector<int>& cell_indices) const;
};
template<class T>
int Multitable<T>::GetCellGlobalIndex(const vector<int>& indices) const {
if(indices.empty()) {
throw std::logic_error("Empty indices array!");
}
int global_index = 0;
int subtable_capacity = table.size();
for(int dimension_index = 0; dimension_index < dimensions.size(); ++dimension_index) {
subtable_capacity = subtable_capacity / dimensions[dimension_index];
global_index += subtable_capacity * indices[dimension_index];
}
return global_index;
}
template<class T>
void Multitable<T>::Resize(const vector<int>& new_dimensions, T value) {
int table_size = 1;
dimensions = new_dimensions;
for(int dimension_index = 0; dimension_index < new_dimensions.size(); ++dimension_index) {
table_size *= new_dimensions[dimension_index];
}
table.resize(table_size, value);
}
template<class T>
Multitable<T>::Multitable(const vector<int>& dimensions) {
Resize(dimensions);
}
template<class T>
void Multitable<T>::SetValue(T value, const vector<int>& indices) {
int global_index = GetCellGlobalIndex(indices);
table.at(global_index) = value;
}
template<class T>
T Multitable<T>::GetValue(const vector<int>& indices) {
int global_index = GetCellGlobalIndex(indices);
return table.at(global_index);
}