Changeset e07bbbc in mainline


Ignore:
Timestamp:
2018-07-05T21:41:18Z (6 years ago)
Author:
Dzejrou <dzejrou@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
ad09a52
Parents:
b0b46d59
git-author:
Jaroslav Jindrak <dzejrou@…> (2017-10-28 22:32:21)
git-committer:
Dzejrou <dzejrou@…> (2018-07-05 21:41:18)
Message:

cpp: added basic implementation of all remaining string functions, though most of them still need to be tested

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/cpp/include/impl/string.hpp

    rb0b46d59 re07bbbc  
    818818                size_ -= len;
    819819                ensure_null_terminator_();
    820             }
    821 
    822             iterator erase(const_iterator pos);
    823 
    824             iterator erase(const_iterator pos, const_iterator last);
     820
     821                return *this;
     822            }
     823
     824            iterator erase(const_iterator pos)
     825            {
     826                auto idx = static_cast<size_type>(pos - cbegin());
     827                erase(dx, 1);
     828
     829                return begin() + idx;
     830            }
     831
     832            iterator erase(const_iterator first, const_iterator last)
     833            {
     834                auto idx = static_cast<size_type>(first - cbegin());
     835                auto count = static_cast<size_type>(last - first);
     836                erase(idx, count);
     837
     838                return begin() + idx;
     839            }
    825840
    826841            void pop_back()
     
    938953            }
    939954
    940             size_type find(const basic_string& str, size_type pos = 0) const noexcept;
    941 
    942             size_type find(const value_type* str, size_type pos, size_type n) const;
    943 
    944             size_type find(const value_type* str, size_type pos = 0) const;
    945 
    946             size_type find(value_type c, size_type pos = 0) const;
    947 
    948             size_type rfind(const basic_string& str, size_type pos = npos) const noexcept;
    949 
    950             size_type rfind(const value_type* str, size_type pos, size_type n) const;
    951 
    952             size_type rfind(const value_type* str, size_type pos = npos) const;
    953 
    954             size_type rfind(value_type c, size_type pos = npos) const;
    955 
    956             size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept;
    957 
    958             size_type find_first_of(const value_type* str, size_type pos, size_type n) const;
    959 
    960             size_type find_first_of(const value_type* str, size_type pos = 0) const;
    961 
    962             size_type find_first_of(value_type c, size_type pos = 0) const;
    963 
    964             size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept;
    965 
    966             size_type find_last_of(const value_type* str, size_type pos, size_type n) const;
    967 
    968             size_type find_last_of(const value_type* str, size_type pos = npos) const;
    969 
    970             size_type find_last_of(value_type c, size_type pos = npos) const;
    971 
    972             size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept;
    973 
    974             size_type find_first_not_of(const value_type* str, size_type pos, size_type n) const;
    975 
    976             size_type find_first_not_of(const value_type* str, size_type pos = 0) const;
    977 
    978             size_type find_first_not_of(value_type c, size_type pos = 0) const;
    979 
    980             size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept;
    981 
    982             size_type find_last_not_of(const value_type* str, size_type pos, size_type n) const;
    983 
    984             size_type find_last_not_of(const value_type* str, size_type pos = npos) const;
    985 
    986             size_type find_last_not_of(value_type c, size_type pos = npos) const;
    987 
    988             basic_string substr(size_type pos = 0, size_type n = npos) const;
    989 
    990             int compare(const basic_string& other) const noexcept;
    991 
    992             int compare(size_type pos, size_type n, const basic_string& other) const;
     955            /**
     956             * Note: The following find functions have 4 versions each:
     957             *       (1) takes basic_string
     958             *       (2) takes c string and length
     959             *       (3) takes c string
     960             *       (4) takes value_type
     961             *       According to the C++14 standard, only (1) is marked as
     962             *       noexcept and the other three return the first one with
     963             *       a newly allocated strings (and thus cannot be noexcept).
     964             *       However, allocating a new string results in memory
     965             *       allocation and copying of the source and thus we have
     966             *       decided to follow C++17 signatures of these functions
     967             *       (i.e. all of them being marked as noexcept) and use
     968             *       (2) for the actual implementation (and avoiding any
     969             *       allocations or copying in the process and also providing
     970             *       stronger guarantees to the user).
     971             */
     972
     973            size_type find(const basic_string& str, size_type pos = 0) const noexcept
     974            {
     975                return find(str.c_str(), pos, str.size());
     976            }
     977
     978            size_type find(const value_type* str, size_type pos, size_type len) const noexcept
     979            {
     980                if (empty() || len == 0 || len - pos > size())
     981                    return npos;
     982
     983                size_type idx{pos};
     984
     985                while (idx + len < size_)
     986                {
     987                    if (substr_starts_at_(idx, str, len))
     988                        return idx;
     989                    ++idx;
     990                }
     991
     992                return npos;
     993            }
     994
     995            size_type find(const value_type* str, size_type pos = 0) const noexcept
     996            {
     997                return find(str, pos, traits_type::length(str));
     998            }
     999
     1000            size_type find(value_type c, size_type pos = 0) const noexcept
     1001            {
     1002                if (empty())
     1003                    return npos;
     1004
     1005                for (size_type i = pos; i < size_; ++i)
     1006                {
     1007                    if (traits_type::eq(c, data_[i]))
     1008                        return i;
     1009                }
     1010
     1011                return npos;
     1012            }
     1013
     1014            size_type rfind(const basic_string& str, size_type pos = npos) const noexcept
     1015            {
     1016                return rfind(str.c_str(), pos, str.size());
     1017            }
     1018
     1019            size_type rfind(const value_type* str, size_type pos, size_type len) const noexcept
     1020            {
     1021                if (empty() || len == 0 || len - pos > size())
     1022                    return npos;
     1023
     1024                size_type idx{min(pos, size_ - 1) + 1};
     1025
     1026                while (idx > 0)
     1027                {
     1028                    if (substr_starts_at_(idx - 1, str, len))
     1029                        return idx - 1;
     1030                    --idx;
     1031                }
     1032
     1033                return npos;
     1034            }
     1035
     1036            size_type rfind(const value_type* str, size_type pos = npos) const noexcept
     1037            {
     1038                return rfind(str, pos, traits_type::length(str));
     1039            }
     1040
     1041            size_type rfind(value_type c, size_type pos = npos) const noexcept
     1042            {
     1043                if (empty())
     1044                    return npos;
     1045
     1046                for (size_type i = min(pos, size_ - 1) + 1; i > 0; --i)
     1047                {
     1048                    if (traits_type::eq(c, data_[i - 1]))
     1049                        return i - 1;
     1050                }
     1051
     1052                return npos;
     1053            }
     1054
     1055            size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept
     1056            {
     1057                return find_first_of(str.c_str(), pos, str.size());
     1058            }
     1059
     1060            size_type find_first_of(const value_type* str, size_type pos, size_type len) const noexcept
     1061            {
     1062                if (empty() || len == 0 || pos + len > size())
     1063                    return npos;
     1064
     1065                size_type idx{pos};
     1066
     1067                while (idx < size_)
     1068                {
     1069                    if (is_any_of_(idx, str, len))
     1070                        return idx;
     1071                    ++idx;
     1072                }
     1073
     1074                return npos;
     1075            }
     1076
     1077            size_type find_first_of(const value_type* str, size_type pos = 0) const noexcept
     1078            {
     1079                return find_first_of(str, pos, traits_type::length(str));
     1080            }
     1081
     1082            size_type find_first_of(value_type c, size_type pos = 0) const noexcept
     1083            {
     1084                return find(c, pos);
     1085            }
     1086
     1087            size_type find_last_of(const basic_string& str, size_type pos = npos) const noexcept
     1088            {
     1089                return find_last_of(str.c_str(), pos, str.size());
     1090            }
     1091
     1092            size_type find_last_of(const value_type* str, size_type pos, size_type len) const noexcept
     1093            {
     1094                if (empty())
     1095                    return npos;
     1096
     1097                for (size_type i = min(pos, size_ - 1) + 1; i > 0; --i)
     1098                {
     1099                    if (is_any_of_(i - 1, str, len))
     1100                        return i - 1;
     1101                }
     1102
     1103                return npos;
     1104            }
     1105
     1106            size_type find_last_of(const value_type* str, size_type pos = npos) const noexcept
     1107            {
     1108                return find_last_of(str, pos, traits_type::length(str));
     1109            }
     1110
     1111            size_type find_last_of(value_type c, size_type pos = npos) const noexcept
     1112            {
     1113                return rfind(c, pos);
     1114            }
     1115
     1116            size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept
     1117            {
     1118                return find_first_not_of(str.c_str(), pos, str.size());
     1119            }
     1120
     1121            size_type find_first_not_of(const value_type* str, size_type pos, size_type len) const noexcept
     1122            {
     1123                if (empty() || len == 0 || pos + len > size())
     1124                    return npos;
     1125
     1126                size_type idx{pos};
     1127
     1128                while (idx < size_)
     1129                {
     1130                    if (!is_any_of_(idx, str, len))
     1131                        return idx;
     1132                    ++idx;
     1133                }
     1134
     1135                return npos;
     1136            }
     1137
     1138            size_type find_first_not_of(const value_type* str, size_type pos = 0) const noexcept
     1139            {
     1140                return find_first_not_of(str.c_str(), pos, str.size());
     1141            }
     1142
     1143            size_type find_first_not_of(value_type c, size_type pos = 0) const noexcept
     1144            {
     1145                if (empty())
     1146                    return npos;
     1147
     1148                for (size_type i = pos; i < size_; ++i)
     1149                {
     1150                    if (!traits_type::eq(c, data_[i]))
     1151                        return i;
     1152                }
     1153
     1154                return npos;
     1155            }
     1156
     1157            size_type find_last_not_of(const basic_string& str, size_type pos = npos) const noexcept
     1158            {
     1159                return find_last_not_of(str.c_str(), pos, str.size());
     1160            }
     1161
     1162            size_type find_last_not_of(const value_type* str, size_type pos, size_type len) const noexcept
     1163            {
     1164                if (empty())
     1165                    return npos;
     1166
     1167                for (size_type i = min(pos, size_ - 1) + 1; i > 0; --i)
     1168                {
     1169                    if (!is_one_of_(i - 1, str, len))
     1170                        return i - 1;
     1171                }
     1172
     1173                return npos;
     1174            }
     1175
     1176            size_type find_last_not_of(const value_type* str, size_type pos = npos) const noexcept
     1177            {
     1178                return find_last_not_of(str, pos, traits_type::length(str));
     1179            }
     1180
     1181            size_type find_last_not_of(value_type c, size_type pos = npos) const noexcept
     1182            {
     1183                if (empty())
     1184                    return npos;
     1185
     1186                pos = min(pos, size_ - 1);
     1187
     1188                for (size_type i = min(pos, size_ - 1) + 1; i > 1; --i)
     1189                {
     1190                    if (!traits_type::eq(c, data_[i - 1]))
     1191                        return i - 1;
     1192                }
     1193
     1194                return npos;
     1195            }
     1196
     1197            basic_string substr(size_type pos = 0, size_type n = npos) const
     1198            {
     1199                // TODO: throw out_of_range if pos > size().
     1200                auto len = min(n, size_ - pos);
     1201                return basic_string{data() + pos, len};
     1202            }
     1203
     1204            int compare(const basic_string& other) const noexcept
     1205            {
     1206                auto len = min(size(), other.size());
     1207                auto comp = traits_type::compare(data_, other.data(), len);
     1208
     1209                if (comp != 0)
     1210                    return comp;
     1211                else if (size() == other.size())
     1212                    return 0;
     1213                else if (size() > other.size())
     1214                    return 1;
     1215                else if (size() < other.size())
     1216                    return -1;
     1217            }
     1218
     1219            int compare(size_type pos, size_type n, const basic_string& other) const
     1220            {
     1221                return basic_string{*this, pos, n}.compare(other);
     1222            }
    9931223
    9941224            int compare(size_type pos1, size_type n1, const basic_string& other,
    995                         size_type pos2, size_type n2 = npos) const;
    996 
    997             int compare(const value_type* other) const;
    998 
    999             int compare(size_type pos, size_type n, const value_type* other) const;
    1000 
    1001             int compare(size_type pos1, size_type n1,
    1002                         const value_type* other, size_type n2) const;
     1225                        size_type pos2, size_type n2 = npos) const
     1226            {
     1227                return basic_string{*this, pos1, n1}.compare(basic_string{other, pos2, n2});
     1228            }
     1229
     1230            int compare(const value_type* other) const
     1231            {
     1232                return compare(basic_string(other));
     1233            }
     1234
     1235            int compare(size_type pos, size_type n, const value_type* other) const
     1236            {
     1237                return basic_string{*this, pos, n}.compare(basic_string{other});
     1238            }
     1239
     1240            int compare(size_type pos, size_type n1,
     1241                        const value_type* other, size_type n2) const
     1242            {
     1243                return basic_string{*this, pos, n1}.compare(basic_string{other, n2});
     1244            }
    10031245
    10041246        private:
     
    11021344                traits_type::assign(data_[size_], value_type{});
    11031345            }
     1346
     1347            bool is_one_of_(size_type idx, const basic_string& str) const
     1348            {
     1349                auto cstr = str.c_str();
     1350                for (size_type i = 0; i < str.size(); ++i)
     1351                {
     1352                    if (traits_type::eq(data_[idx], cstr[i]))
     1353                        return true;
     1354                }
     1355
     1356                return false;
     1357            }
     1358
     1359            bool substr_starts_at_(size_type idx, const value_type* str, size_type len) const
     1360            {
     1361                size_type i{};
     1362                for (i = 0; i < len; ++i)
     1363                {
     1364                    if (!traits_type::eq(data_[idx + i], str[i]))
     1365                        break;
     1366                }
     1367
     1368                return i == len;
     1369            }
    11041370    };
    11051371}
Note: See TracChangeset for help on using the changeset viewer.