mmCEsim 0.3.0
mmWave Channel Estimation Simulation
value_vec.h
Go to the documentation of this file.
1
12#ifndef _EXPORT_VALUE_VEC_H_
13#define _EXPORT_VALUE_VEC_H_
14
15#include "utils.h"
16#include "yaml.h"
17#include <string>
18#include <vector>
19
20template <typename T>
21class Value_Vec {
22 public:
23 Value_Vec(const std::string& str, bool error_out_of_bound = false, T out_of_bound_val = 0);
24
25 Value_Vec(const YAML::Node& node, bool error_out_of_bound = false, T out_of_bound_val = 0);
26
27 T operator[](size_t index) const;
28
29 T max() const;
30
31 T min() const;
32
33 std::string asStr(bool quoted = false) const;
34
35 size_t size() const noexcept;
36
37 private:
38 std::string removeBracket(const std::string& str);
39
40 void parseToken(const std::string& s);
41
42 private:
43 std::vector<T> _data;
46};
47
48template <typename T>
49Value_Vec<T>::Value_Vec(const std::string& str, bool error_out_of_bound, T out_of_bound_val)
50 : _error_out_of_bound(error_out_of_bound), _out_of_bound_val(out_of_bound_val) {
51 std::vector<std::string> tokens;
52 std::stringstream ss(removeBracket(str));
53 std::string buf;
54 // split by ','
55 while (ss.good()) {
56 std::getline(ss, buf, ',');
57 tokens.push_back(buf);
58 }
59 for (auto&& token : tokens) { parseToken(token); }
60}
61
62template <typename T>
63Value_Vec<T>::Value_Vec(const YAML::Node& node, bool error_out_of_bound, T out_of_bound_val)
64 : _error_out_of_bound(error_out_of_bound), _out_of_bound_val(out_of_bound_val) {
65 if (node.IsScalar()) {
66 std::vector<std::string> tokens;
67 std::stringstream ss(removeBracket(node.as<std::string>()));
68 std::string buf;
69 // split by ','
70 while (ss.good()) {
71 std::getline(ss, buf, ',');
72 tokens.push_back(buf);
73 }
74 for (auto&& token : tokens) { parseToken(token); }
75 } else {
76 for (auto&& token : node) { parseToken(token.as<std::string>()); }
77 }
78}
79
80template <typename T>
81inline std::string Value_Vec<T>::removeBracket(const std::string& str) {
82 if (str.size() < 2) return str;
83 if (str[0] == '[' && *(str.end() - 1) == ']') return str.substr(1, str.length() - 2);
84 else return str;
85}
86
87template <typename T>
88void Value_Vec<T>::parseToken(const std::string& s) {
89 // find first ':'
90 size_t first_colon = s.find(':');
91 size_t second_colon = std::string::npos;
92 if (first_colon != std::string::npos) {
93 second_colon = s.find(':', first_colon + 1);
94 if (second_colon != std::string::npos) {
95 // 2 colons
96 T v1 = strAs<T>(s.substr(0, first_colon));
97 T v_ = strAs<T>(s.substr(first_colon + 1, second_colon - first_colon));
98 T v2 = strAs<T>(s.substr(second_colon + 1, s.size() - 1 - second_colon));
99 if (v_ == 0) {
100 if (v1 == v2) {
101 _data.push_back(strAs<T>(s));
102 } else {
103 // ERROR! step is stuck at 0.
104 // TODO: error handling
105 assert("step size as 0 in 2 colons specification.");
106 }
107 } else if (v_ > 0) {
108 for (T v = v1; v <= v2 + 1E-12; v += v_) { _data.push_back(v); }
109 } else {
110 for (T v = v1; v + 1E-12 >= v2; v += v_) { _data.push_back(v); }
111 }
112 } else {
113 // 1 colon
114 T v1 = strAs<T>(s.substr(0, first_colon));
115 T v2 = strAs<T>(s.substr(first_colon + 1, s.size() - 1 - first_colon));
116 if (v1 <= v2) {
117 for (T v = v1; v <= v2 + 1E-12; v += 1) { _data.push_back(v); }
118 } else {
119 // avoid the unsigned problem when subtracting from 0;
120 for (T v = v2 + 1; v + 1E-12 >= v1 + 1; v -= 1) { _data.push_back(v - 1); }
121 }
122 }
123 } else {
124 _data.push_back(strAs<T>(s));
125 }
126}
127
128template <typename T>
129T Value_Vec<T>::operator[](size_t index) const {
130 // std::cout << "Value Vec Data Size: " << _data.size() << std::endl;
131 if (index < _data.size()) {
132 return _data[index];
133 } else {
134 if (_error_out_of_bound) {
135 // TODO: needs an elegant way of raising error.
136 assert(false && "Out of bound for a value_vec!");
137 }
138 // std::cout << "out of bound" << _out_of_bound_val << "\n";
139 return _out_of_bound_val;
140 }
141}
142
143// TODO: Bette min() and max() Implementation
144// This time the implementation of max() and min() is general,
145// without considering the sequence of the data.
146template <typename T>
148 if (_data.size() == 0) return 0;
149 T max = _data[0];
150 for (auto&& v : _data) {
151 if (v > max) max = v;
152 }
153 return max;
154}
155
156template <typename T>
158 if (_data.size() == 0) return 0;
159 T min = _data[0];
160 for (auto&& v : _data) {
161 if (v < min) min = v;
162 }
163 return min;
164}
165
166template <typename T>
167std::string Value_Vec<T>::asStr(bool quoted) const {
168 if (_data.size() == 0) return "";
169 std::string s;
170 for (auto i = _data.cbegin(); i + 1 != _data.end(); ++i) {
171 if (quoted) s += "\"" + mmce::to_string(*i) + "\", ";
172 else s += mmce::to_string(*i) + ", ";
173 }
174 if (quoted) s += "\"" + mmce::to_string(*(_data.end() - 1)) + "\"";
175 else s += mmce::to_string(*(_data.end() - 1));
176 return s;
177}
178
179template <typename T>
180inline size_t Value_Vec<T>::size() const noexcept {
181 return _data.size();
182}
183
184#endif
Definition: value_vec.h:21
std::string removeBracket(const std::string &str)
Definition: value_vec.h:81
Value_Vec(const std::string &str, bool error_out_of_bound=false, T out_of_bound_val=0)
Definition: value_vec.h:49
bool _error_out_of_bound
Definition: value_vec.h:44
T min() const
Definition: value_vec.h:157
void parseToken(const std::string &s)
Definition: value_vec.h:88
T max() const
Definition: value_vec.h:147
T operator[](size_t index) const
Definition: value_vec.h:129
std::vector< T > _data
Definition: value_vec.h:43
size_t size() const noexcept
Definition: value_vec.h:180
std::string asStr(bool quoted=false) const
Definition: value_vec.h:167
T _out_of_bound_val
Definition: value_vec.h:45
static std::string to_string(const T &x)
Change a number to string.
Definition: utils.h:203
str
Definition: version_bump.py:14
Utilities.
Wrapper for yaml-cpp for static linking.