File indexing completed on 2024-04-28 17:06:31

0001 /*
0002     SPDX-FileCopyrightText: 2006 Shie Erlich <erlich@users.sourceforge.net>
0003     SPDX-FileCopyrightText: 2006-2022 Krusader Krew <https://krusader.org>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #ifndef TSTRING_H
0009 #define TSTRING_H
0010 
0011 #include <cassert>
0012 #include <utility>
0013 
0014 // QtCore
0015 #include <QList>
0016 #include <QString>
0017 
0018 template<class T>
0019 class TagString_t
0020 {
0021     QString str;
0022     typedef QList<std::pair<uint, T>> taglist; // may change
0023     taglist tags;
0024 
0025 public:
0026     TagString_t(const QString &s)
0027         : str(s)
0028     {
0029     } // implicit conversion
0030     TagString_t()
0031     {
0032     }
0033     bool isSimple() const
0034     {
0035         return tags.empty();
0036     }
0037     const QString &string() const
0038     {
0039         return str;
0040     }
0041     unsigned length() const
0042     {
0043         return str.length();
0044     }
0045     TagString_t mid(unsigned idx, unsigned len = ~0) const;
0046     TagString_t left(unsigned) const;
0047     TagString_t right(unsigned) const;
0048     void insert(uint, const QString &s);
0049     int find(QChar c, int index = 0, bool cs = true) const
0050     {
0051         return str.indexOf(c, index, (cs ? Qt::CaseSensitive : Qt::CaseInsensitive));
0052     }
0053     TagString_t &operator+=(const TagString_t &s);
0054     typename taglist::const_iterator tagsBegin() const
0055     {
0056         return tags.begin();
0057     }
0058     typename taglist::const_iterator tagsEnd() const
0059     {
0060         return tags.end();
0061     }
0062     typename taglist::iterator tagsBegin()
0063     {
0064         return tags.begin();
0065     }
0066     typename taglist::iterator tagsEnd()
0067     {
0068         return tags.end();
0069     }
0070     void insertTag(uint pos, const T &t);
0071     void eraseTag(const typename taglist::iterator &which)
0072     {
0073         tags.erase(which);
0074     }
0075     /* void insert(uint idx,const QString&);
0076      void insert(uint idx,const char*);
0077      void addTag(uint);
0078      void remove(uint start,uint len);*/
0079 };
0080 
0081 template<class T>
0082 TagString_t<T> TagString_t<T>::mid(unsigned idx, unsigned len) const
0083 {
0084     TagString_t ret(str.mid(idx, len));
0085     unsigned max = idx + len;
0086     if (max < idx)
0087         max = ~0;
0088     for (typename taglist::const_iterator it = tags.begin(), end = tags.end(); it != end; ++it) {
0089         if ((*it).first >= idx && (*it).first < max)
0090             ret.tags.push_back(*it);
0091     }
0092     return ret;
0093 }
0094 
0095 template<class T>
0096 TagString_t<T> TagString_t<T>::left(unsigned len) const
0097 {
0098     TagString_t ret(str.left(len));
0099     for (typename taglist::const_iterator it = tags.begin(), end = tags.end(); it != end; ++it) {
0100         if ((*it).first < len)
0101             ret.tags.push_back(*it);
0102     }
0103     return ret;
0104 }
0105 
0106 template<class T>
0107 TagString_t<T> TagString_t<T>::right(unsigned len) const
0108 {
0109     TagString_t ret(str.right(len));
0110     for (typename taglist::const_iterator it = tags.begin(), end = tags.end(); it != end; ++it) {
0111         if ((*it).first >= str.length() - len)
0112             ret.tags.push_back(*it);
0113     }
0114     return ret;
0115 }
0116 
0117 template<class T>
0118 void TagString_t<T>::insert(uint idx, const QString &s)
0119 {
0120     str.insert(idx, s);
0121     const unsigned disp = s.length();
0122     for (typename taglist::iterator it = tags.begin(), end = tags.end(); it != end; ++it) {
0123         if ((*it).first >= idx)
0124             (*it).first += disp;
0125     }
0126 }
0127 
0128 template<class T>
0129 TagString_t<T> &TagString_t<T>::operator+=(const TagString_t &s)
0130 {
0131     str += s.str;
0132     const unsigned disp = length();
0133     for (typename taglist::const_iterator it = s.tags.begin(), end = s.tags.end(); it != end; ++it) {
0134         tags.push_back(std::make_pair((*it).first + disp, (*it).second));
0135     }
0136     return *this;
0137 }
0138 
0139 template<class T>
0140 void TagString_t<T>::insertTag(uint pos, const T &t)
0141 {
0142     assert(pos <= length());
0143     tags.push_back(std::make_pair(pos, t));
0144 }
0145 
0146 #endif