2626#include < cwctype>
2727#include < format>
2828#include < map>
29+ #include < ranges>
2930#include < span>
3031#include < stdexcept>
3132#include < string_view>
@@ -106,7 +107,8 @@ namespace pcs // i.e. "pythonic c++ strings"
106107 {
107108 public:
108109 // === Wrappers ========================================
109- using MyBaseClass = std::basic_string<CharT>;
110+ using MyBaseClass = std::basic_string<CharT>;
111+ using MyStringView = std::basic_string_view<CharT>;
110112
111113 using traits_type = MyBaseClass::traits_type;
112114 using value_type = MyBaseClass::value_type;
@@ -141,6 +143,7 @@ namespace pcs // i.e. "pythonic c++ strings"
141143
142144 template <class StringViewLike >
143145 explicit CppStringT (const StringViewLike& svl) : MyBaseClass(svl) {}
146+
144147 template <class StringViewLike >
145148 CppStringT (const StringViewLike& svl, size_type pos, size_type n) : MyBaseClass(svl, pos, n) {}
146149
@@ -888,7 +891,7 @@ namespace pcs // i.e. "pythonic c++ strings"
888891
889892
890893 // --- rpartition() -------------------------------------
891- /* * Split the string at the last occurrence of sep, and returns a 3-items vector containing the part before the separator, the separator itself, and the part after the separator.
894+ /* * Splits the string at the last occurrence of sep, and returns a 3-items vector containing the part before the separator, the separator itself, and the part after the separator.
892895 *
893896 * If the separator is not found, returns a 3-items vector
894897 * containing the string itself, followed by two empty strings.
@@ -909,67 +912,119 @@ namespace pcs // i.e. "pythonic c++ strings"
909912
910913
911914 // --- rsplit() ----------------------------------------
912- /* * \brief Returns a vector of the words in the string, as seperated with whitespace strings. */
915+ /* * \brief Returns a vector of the words in the whole string, as seperated with whitespace strings. */
913916 inline std::vector<CppStringT> rsplit () const noexcept
914917 {
915918 return split ();
916919 }
917920
918- /* * \brief Returns a vector of the words in the string, using sep as the delimiter string. */
921+ /* * \brief Returns a vector of the words in the whole string, using sep as the delimiter string. */
919922 inline std::vector<CppStringT> rsplit (const CppStringT& sep) const noexcept
920923 {
921924 return split (sep);
922925 }
923926
924- /* * \brief Returns a vector of the words in the string, as seperated with whitespace strings.
925- *
926- * At most maxsplit splits are done, the rightmost ones.
927- */
927+ /* * \brief Returns a vector of the words in the string, as seperated with whitespace strings. At most maxsplit splits are done, the rightmost ones. */
928928 std::vector<CppStringT> rsplit (const size_type maxsplit) const noexcept
929929 {
930- if (maxsplit == 0 )
931- return *this ;
930+ std::vector<CppStringT> res{};
932931
933- constexpr CppStringT spc2 (" " );
934- constexpr CppStringT spc (value_type (' ' ));
935- CppStringT tmp = *this ;
936- while (tmp.contains (spc2))
937- tmp = tmp.replace (spc2, spc);
932+ if (maxsplit == 0 ) {
933+ res.push_back (*this );
934+ }
935+ else {
936+ const CppStringT whitespace (value_type (' ' ));
937+ std::vector<CppStringT> all_words{ this ->split (whitespace) };
938+
939+ size_type count = maxsplit;
940+ auto word_it = all_words.crbegin ();
941+ size_type last_split_index = all_words.size ();
942+ while (count > 0 && word_it != all_words.crend ()) {
943+ if (!word_it->empty ()) {
944+ res.insert (res.cbegin (), *word_it);
945+ --count;
946+ --last_split_index;
947+ }
948+ word_it++;
949+ }
950+
951+ size_type chars_count = last_split_index;
952+ while (last_split_index > 0 ) {
953+ chars_count += all_words[last_split_index].size ();
954+ --last_split_index;
955+ }
956+ if (chars_count > 0 )
957+ res.insert (res.cbegin (), this ->substr (0 , chars_count));
958+ /*
959+ constexpr CppStringT spc2(" ");
960+ constexpr CppStringT spc(value_type(' '));
961+ CppStringT tmp = *this;
962+ while (tmp.contains(spc2))
963+ tmp = tmp.replace(spc2, spc);
964+
965+ res = tmp->rsplit(spc, maxsplit);
966+ */
967+ }
938968
939- return this -> rsplit (spc, maxsplit) ;
969+ return res ;
940970 }
941971
942972 /* * \brief Returns a vector of the words in the string, using sep as the delimiter string.
943973 *
944- * At most maxsplit splits are done, the rightmost ones. Except
945- * for splitting from the right, rsplit() behaves like split()].
974+ * At most maxsplit splits are done, the rightmost ones.
946975 */
947976 std::vector<CppStringT> rsplit (const CppStringT& sep, const size_type maxsplit) const noexcept
948977 {
949978 std::vector<CppStringT> res{};
950979
951- std::vector<CppStringT> indexes{};
952- CppStringT tmp = *this ;
953- size_type count = maxsplit;
954- size_type index;
955- while ((index = tmp.rfind (sep)) != CppStringT::npos && count > 0 ) {
956- indexes.insert (indexes.begin (), index);
957- if (index == 0 )
958- break ;
959- tmp = tmp.substr (0 , index-1 );
960- count--;
980+ if (maxsplit == 0 ) {
981+ res.push_back ({ *this });
961982 }
962-
963- if (indexes.size () == 0 )
964- res.push_back (*this );
965983 else {
966- index = 0 ;
967- for (const size_type ndx: indexes) {
968- res.push_back (this ->substr (index, ndx - index));
969- index = ndx + 1 ;
984+ std::vector<CppStringT> all_words{ this ->split (sep) };
985+
986+ size_type count = maxsplit;
987+ auto word_it = all_words.crbegin ();
988+ size_type last_split_index = all_words.size ();
989+ while (count > 0 && word_it != all_words.crend ()) {
990+ res.insert (res.cbegin (), *word_it);
991+ --count;
992+ --last_split_index;
993+ word_it++;
994+ }
995+
996+ size_type chars_count = last_split_index;
997+ while (last_split_index > 0 ) {
998+ chars_count += all_words[last_split_index].size ();
999+ --last_split_index;
1000+ }
1001+ if (chars_count > 0 )
1002+ res.insert (res.cbegin (), this ->substr (0 , chars_count));
1003+ /*
1004+ std::vector<CppStringT> indexes{};
1005+ CppStringT tmp = *this;
1006+ size_type count = maxsplit;
1007+ size_type index;
1008+ while ((index = tmp.rfind(sep)) != CppStringT::npos && count > 0) {
1009+ indexes.insert(indexes.begin(), index);
1010+ if (index == 0)
1011+ break;
1012+ tmp = tmp.substr(0, index-1);
1013+ count--;
1014+ }
1015+
1016+ if (indexes.size() == 0)
1017+ res.push_back(*this);
1018+ else {
1019+ index = 0;
1020+ for (const size_type ndx: indexes) {
1021+ res.push_back(this->substr(index, ndx - index));
1022+ index = ndx + 1;
9701023 }
9711024 res.push_back(this->substr(index, this->size() - index));
1025+ */
9721026 }
1027+
9731028 return res;
9741029 }
9751030
0 commit comments