16#ifndef SIMICS_TYPE_HIERARCHICAL_OBJECT_NAME_H
17#define SIMICS_TYPE_HIERARCHICAL_OBJECT_NAME_H
40 :
std::string_view() {}
44 :
std::string_view(s, count) {
50 :
std::string_view(s) {
58 return substr(0, find(
'['));
76 throw std::invalid_argument(
"Invalid width 0");
85 for (
auto it = sizes_and_strides.rbegin();
86 it != sizes_and_strides.rend(); ++it) {
87 if (it->second != 0) {
90 if (it == sizes_and_strides.rbegin()) {
95 it->second = (it - 1)->first * (it - 1)->second;
99 std::map<std::string, size_t> names_to_offsets;
100 std::vector<size_t> indices(sizes_and_strides.size(), 0);
101 generateNamesToOffsets(sizes_and_strides, 0, &indices,
103 return names_to_offsets;
114 std::size_t content_pos = npos;
115 std::vector<std::pair<size_t, size_t>> dims_;
116 for (
size_t i = 0; i < s.size(); ++i) {
119 if (content_pos != npos) {
120 throw std::logic_error(
"Name has unbalanced brackets");
123 }
else if (c ==
']') {
124 if (content_pos == npos) {
125 throw std::logic_error(
"Name has unbalanced brackets");
127 if (content_pos == i) {
128 throw std::logic_error(
"Name has nothing in brackets");
130 const auto &[size, stride] = sizeAndStride(
131 s.substr(content_pos, i - content_pos));
133 throw std::logic_error(
"Dimension size is 0");
135 dims_.push_back({size, stride});
140 if (content_pos != npos) {
141 throw std::logic_error(
"Name has unbalanced brackets");
151 static constexpr bool isalpha(
char c) {
152 return (c >=
'a' && c <=
'z') || (c >=
'A' && c <=
'Z');
155 static constexpr bool isalnum(
char c) {
156 return isalpha(c) || (c >=
'0' && c <=
'9');
161 constexpr void validate_name()
const {
167 throw std::invalid_argument(
"Empty name is not allowed");
169 if (!isalpha(front())) {
170 throw std::invalid_argument(
171 std::string(
"Name (") + data() \
172 +
") does not begin with an alphabetic character");
177 if (c !=
'_' && !isalnum(c)) {
178 throw std::invalid_argument(
179 std::string(
"Character (") + c \
180 +
") is not allowed to use in a name");
185 std::pair<size_t, size_t> sizeAndStride(std::string_view s)
const {
186 auto stride_pos = s.find(
" stride ");
191 if (stride_pos != npos) {
192 size = std::stoi(s.substr(0, stride_pos).data());
193 stride = std::stoi(s.substr(stride_pos + 8).data());
195 if (s.find_first_not_of(
"0123456789") != npos) {
196 throw std::invalid_argument(
"non-digit character");
198 size = std::stoi(s.data());
200 }
catch (
const std::exception &e) {
201 throw std::invalid_argument(
202 std::string(
"Array contents are malformed: ") + e.what());
205 return {size, stride};
208 void generateNamesToOffsets(
const std::vector<std::pair<size_t, size_t>>
211 std::vector<size_t> *indices,
212 std::map<std::string, size_t>
213 *names_to_offsets)
const {
214 if (current_dim == dims_info.size()) {
219 for (
size_t i = 0; i < indices->size(); i++) {
220 name +=
"[" + std::to_string((*indices)[i]) +
"]";
221 offset += (*indices)[i] * dims_info[i].second;
223 (*names_to_offsets)[name] = offset;
226 for (
size_t i = 0; i < dims_info[current_dim].first; i++) {
227 (*indices)[current_dim] = i;
228 generateNamesToOffsets(dims_info, current_dim + 1,
229 indices, names_to_offsets);
Definition: hierarchical-object-name.h:37
std::map< std::string, size_t > arrayNamesToOffsets(size_t width) const
Definition: hierarchical-object-name.h:74
constexpr HierarchicalObjectName(const char *s, std::size_t count)
Definition: hierarchical-object-name.h:43
std::vector< std::pair< size_t, size_t > > arraySizesAndStrides() const
Definition: hierarchical-object-name.h:108
constexpr std::string_view array_str() const
Definition: hierarchical-object-name.h:62
constexpr HierarchicalObjectName(const HierarchicalObjectName &other) noexcept=default
constexpr HierarchicalObjectName() noexcept
Definition: hierarchical-object-name.h:39
constexpr HierarchicalObjectName(const char *s)
Definition: hierarchical-object-name.h:49
constexpr std::string_view base_name() const
Definition: hierarchical-object-name.h:57
Definition: attr-value.h:23
Definition: common-types.h:63