Skip to content

Commit f512977

Browse files
committed
#194-Implement operator () with slices
Completed. Still to be tested.
1 parent 3f25a77 commit f512977

File tree

1 file changed

+47
-51
lines changed

1 file changed

+47
-51
lines changed

cpp-strings/cppstrings.h

Lines changed: 47 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,62 +1072,47 @@ namespace pcs // i.e. "pythonic c++ strings"
10721072
* and negative start or stop is relative to the end of the
10731073
* string.
10741074
* Notice: the stop value specifies an out of bounds index.
1075+
* \see class Slice and all its inheriting classes.
10751076
*/
1076-
inline CppStringT operator() (const long stop) const noexcept
1077-
{
1078-
size_type end{ stop < 0 ? this->size() + stop : stop };
1079-
return this->substr(0, end);
1080-
}
1081-
1082-
/** \brief Generates a new string according to the specified slice. */
1083-
inline CppStringT operator() (const long start, const long stop) const noexcept
1084-
{
1085-
const size_type length{ this->size() };
1086-
size_type begin{ start < 0 ? length + start : start };
1087-
size_type end{ stop < 0 ? length + stop : stop };
1088-
1089-
if (begin >= end)
1090-
return CppStringT();
1091-
else
1092-
return this->substr(begin, end - begin);
1093-
}
1077+
template<typename IntT>
1078+
requires std::is_signed_v<IntT>
1079+
CppStringT operator() (Slice<IntT> slice) const noexcept
1080+
{
1081+
// optimization on 1 by 1 step
1082+
if (slice.step() == 1) {
1083+
slice.begin(*this);
1084+
if (slice.start() < slice.stop())
1085+
return this->substr(slice.start(), slice.stop() - slice.start() + 1);
1086+
else
1087+
return CppStringT();
1088+
}
10941089

1095-
/** \brief Generates a new string according to the specified slice. */
1096-
CppStringT operator() (const long start, const long stop, const long step) const noexcept
1097-
{
10981090
CppStringT res{};
10991091

1100-
const size_type length{ this->size() };
1101-
size_type begin{ start < 0 ? length + start : start };
1102-
size_type end{ stop < 0 ? length + stop : stop };
1103-
1104-
if (step < 0) {
1105-
if (begin >= length)
1106-
begin = length - 1;
1107-
if (end < 0)
1108-
end = -1;
1109-
1110-
if (begin > end) {
1111-
for (size_type i = begin; i > end; i += step)
1112-
res += (*this)[i];
1113-
}
1114-
}
1115-
else if (step > 0) {
1116-
if (begin < 0)
1117-
begin = 0;
1118-
if (end > length)
1119-
end = length;
1120-
1121-
if (begin < end) {
1122-
for (size_type i = begin; i < end; i += step)
1123-
res += (*this)[i];
1124-
}
1092+
// optimization on reversed 1 by 1 step
1093+
if (slice.step() == -1) {
1094+
slice.begin(*this);
1095+
if (slice.stop() < slice.start()) {
1096+
res = this->substr(slice.stop(), slice.start() - slice.stop() + 1);
1097+
std::ranges::reverse(res); // notice: may use vectorization if available
1098+
}
1099+
return res;
11251100
}
11261101

1102+
// finally, no trivial optimization -- and naive implementation...
1103+
for (slice.begin(*this); !slice.end(); ++slice)
1104+
res += (*this)[*slice];
1105+
11271106
return res;
11281107
}
11291108

1130-
1109+
/** \brief Generates a new string according to the specified slicing values. */
1110+
inline CppStringT operator() (const long long start, const long long stop, const long long step = 1) const noexcept
1111+
{
1112+
Slice<long long> slice(start, stop, step);
1113+
return (*this)(slice);
1114+
}
1115+
11311116

11321117
//--- operator * --------------------------------------
11331118
/** \brief Generates a new string with count times the content of this string. */
@@ -1888,6 +1873,11 @@ namespace pcs // i.e. "pythonic c++ strings"
18881873
return _index;
18891874
}
18901875

1876+
//--- properties ----------------------------------
1877+
inline IntT start() { return _start; } //!< Returns the start index of this slide
1878+
inline IntT stop() { return _stop; } //!< Returns the stop index of this slide
1879+
inline IntT step() { return _step; } //!< Returns the step value of this slide
1880+
18911881

18921882
private:
18931883
IntT _start{ 0 };
@@ -1898,15 +1888,21 @@ namespace pcs // i.e. "pythonic c++ strings"
18981888

18991889
const IntT _prepare_iterating(const IntT str_size) noexcept
19001890
{
1901-
if (_start == DEFAULT)
1902-
_start = 0;
1891+
if (_start == DEFAULT) {
1892+
if (_step < 0 && _step != DEFAULT)
1893+
_start = str_size - 1;
1894+
else
1895+
_start = 0;
1896+
}
19031897
else if (_start < 0) {
19041898
_start += str_size;
19051899
if (_start < 0)
19061900
_start = 0;
19071901
}
1908-
else if (_start >= str_size)
1909-
_start = str_size - 1;
1902+
else if (_start >= str_size) {
1903+
if (_step < 0 && _step != DEFAULT)
1904+
_start = str_size - 1;
1905+
}
19101906

19111907
if (_stop == DEFAULT) {
19121908
if (_step < 0 && _step != DEFAULT)

0 commit comments

Comments
 (0)