74 Range(
const std::string &str) :
Range(parseRange(str))
80 static Range parseRange(
const std::string &str)
83 int start, stop, step;
86 if(std::regex_match(str, sm, std::regex(
"^\\s*(-?\\d+)?\\s*:\\s*(-?\\d+)?\\s*:\\s*(-?\\d+)?\\s*$")))
89 start = (sm[1] ==
"")? 0: std::stoi( sm[1] );
90 stop = (sm[2] ==
"")? 0: std::stoi( sm[2] );
91 step = (sm[3] ==
"")? 1: std::stoi( sm[3] );
95 else if(std::regex_match(str, sm, std::regex(
"^\\s*(-?\\d+)?\\s*:\\s*(-?\\d+)?\\s*$")))
98 start = (sm[1] ==
"")? 0: std::stoi( sm[1] );
99 stop = (sm[2] ==
"")? 0: std::stoi( sm[2] );
107 throw std::invalid_argument(
"Invalid slice format");
110 return {start, stop, step,
has_stop};
119 using std::vector<Dtype, Allocator>::vector;
123 template <
typename U = Dtype>
124 auto toString(
int indentLevel = 0)
const ->
125 typename std::enable_if<std::integral_constant<bool, std::is_arithmetic<U>::value || std::is_same<U, std::string>::value>::value, std::string>::type
127 if (this->empty())
return "[ ]";
128 std::stringstream ss;
129 for (
size_t i = 0; i < this->size(); ++i) {
130 ss << (i==0?
"[ ":
"")
132 << (i != this->size()-1 ?
", " :
" ]");
138 template <
typename U = Dtype>
139 auto toString(
int indentLevel = 0)
const ->
140 decltype(std::declval<U>().toString())
142 if (this->empty())
return "[ ]";
143 std::stringstream ss;
144 std::string indent(indentLevel * 2,
' ');
145 for (
size_t i = 0; i < this->size(); ++i) {
147 ss << (i==0?
"[\n":
"")
149 <<
" " << (*
this)[i].toString(indentLevel + 1)
150 << (i != this->size()-1 ?
"," :
"")
161 if (idx < 0)
throw std::out_of_range(
"Index out of range");
164 return std::vector<Dtype>::at(idx);
167 const Dtype& at(
int idx)
const
171 if (idx < 0)
throw std::out_of_range(
"Index out of range");
174 return std::vector<Dtype>::at(idx);
179 return os << vec.toString();
196 static_assert(dim >= 1,
"Dimension must be greater than zero!");
199 template<
typename... Args>
208 template<
typename T, std::
size_t M,
typename =
typename std::enable_if<(M < dim)>::type>
209 Inner(const Inner<T, M>& lowerDimInner)
221 template<
typename... Indices,
222 typename std::enable_if<(
sizeof...(Indices) > 0),
int>::type = 0,
223 typename std::enable_if<
conjunction<std::is_integral<Indices>...>::value,
int>::type = 0>
224 auto operator()(
int idx, Indices... indices) ->
decltype(this->at(idx)(indices...))
226 return this->at(idx).operator()(indices...);
229 template<
typename... Indices,
230 typename std::enable_if<(
sizeof...(Indices) > 0),
int>::type = 0,
231 typename std::enable_if<conjunction<std::is_integral<Indices>...>::value,
int>::type = 0>
232 const Inner<Dtype, dim-1>&
operator()(
int idx, Indices... indices)
const
234 return this->at(idx).operator()(indices...);
238 Inner<Dtype, dim-1>& operator()(
int idx)
240 return this->at(idx);
243 const Inner<Dtype, dim-1>& operator()(
int idx)
const
245 return this->at(idx);
255 Inner<Dtype, dim> operator[](
const std::string& input)
const
257 std::string str(input);
259 std::array<Range, dim> slices;
262 std::regex re(
"\\s*,\\s*");
263 std::sregex_token_iterator first{str.begin(), str.end(), re, -1}, last;
264 for (; first != last; ++first) {
265 if(i >= dim)
throw std::invalid_argument(
"Too many slices");
266 slices[i++] = Range::parseRange(*first);
269 return slice(slices, 0, i);
273 template<std::
size_t length>
274 Inner<Dtype, dim> slice(
const std::array<Range, length> slices,
int start,
const int& end)
const
276 if(start == end)
return *
this;
278 Inner<Dtype, dim> result;
280 Range r = slices[start];
281 std::size_t stop = r.has_stop? r.stop: this->size();
283 for(
int i = r.start; i < stop; i += r.step)
285 result.push_back(this->at(i).slice(slices, start + 1, end));
304 Dtype& operator()(
int idx) {
305 return this->at(idx);
308 const Dtype& operator()(
int idx)
const {
309 return this->at(idx);
315 std::string str(input);
316 std::array<Range, 1> slices;
318 Range range = Range::parseRange(str);
321 return slice(slices);
324 template<std::
size_t length>
325 Inner<Dtype, 1> slice(
const std::array<Range, length> slices,
int start,
const int& end)
const
327 if(start == end)
return *
this;
331 Range s = slices[start];
332 std::size_t stop = s.
has_stop? s.stop: this->size();
334 for(
int i = s.start; i < stop; i += s.step)
336 result.push_back(this->at(i));
Inner(std::initializer_list< Inner< Dtype, dim - 1 > > initList)
Constructor to handle initializer list for nested lists.
Definition ndarray-11.hpp:204