File indexing completed on 2024-04-28 05:49:26

0001 /*
0002     SPDX-FileCopyrightText: 2022 Waqar Ahmed <waqar.17a@gmail.com>
0003     SPDX-License-Identifier: LGPL-2.0-or-later
0004 */
0005 #pragma once
0006 
0007 #include <QByteArray>
0008 #include <QString>
0009 
0010 #include <charconv>
0011 #include <optional>
0012 #include <string_view>
0013 
0014 class strview : public std::string_view
0015 {
0016 public:
0017     using std::string_view::string_view;
0018     strview(std::string_view s)
0019         : std::string_view(s)
0020     {
0021     }
0022 
0023     QString toString() const
0024     {
0025         return QString::fromUtf8(data(), size());
0026     }
0027     QByteArray toByteArray() const
0028     {
0029         return QByteArray(data(), size());
0030     }
0031 
0032     template<typename Int>
0033     std::optional<Int> to(Int &&value = {}) const
0034     {
0035         auto res = std::from_chars(data(), data() + size(), value);
0036         if (res.ptr == (data() + size())) {
0037             return value;
0038         }
0039         return std::nullopt;
0040     }
0041 };
0042 
0043 template<typename ArrayType>
0044 class ByteArraySplitter
0045 {
0046 public:
0047     ByteArraySplitter(const ArrayType &b, char splitChar)
0048         : data(b)
0049         , s(splitChar)
0050     {
0051     }
0052 
0053     class iterator
0054     {
0055     public:
0056         iterator()
0057         {
0058         }
0059 
0060         iterator(const char *c, size_t size, char split)
0061             : sv(c, size)
0062             , s(size == 0 ? std::string::npos : 0)
0063             , sp(split)
0064         {
0065             e = sv.find(sp, s);
0066         }
0067 
0068         iterator &operator++()
0069         {
0070             auto newPos = sv.find(sp, e == std::string::npos ? e : e + 1);
0071             s = e != std::string::npos ? e + 1 : std::string::npos;
0072             e = newPos;
0073             return *this;
0074         }
0075 
0076         iterator operator++(int)
0077         {
0078             auto old = *this;
0079             auto newPos = sv.find(sp, e == std::string::npos ? e : e + 1);
0080             s = e != std::string::npos ? e + 1 : std::string::npos;
0081             e = newPos;
0082             return old;
0083         }
0084 
0085         strview operator*() const
0086         {
0087             if (s != std::string::npos) {
0088                 return sv.substr(s, e != std::string::npos ? (e - s) : e);
0089             }
0090             return std::string_view(nullptr, 0);
0091         }
0092 
0093         bool operator==(const iterator &r) const
0094         {
0095             return s == r.s && e == r.e && sp == r.sp;
0096         }
0097 
0098         bool operator!=(const iterator &r) const
0099         {
0100             return !(*this == r);
0101         }
0102 
0103     private:
0104         strview sv;
0105         std::size_t s;
0106         std::size_t e;
0107         char sp;
0108     };
0109 
0110     iterator begin() const
0111     {
0112         return iterator(data.data(), data.size(), s);
0113     }
0114 
0115     iterator end() const
0116     {
0117         return iterator(nullptr, 0, s);
0118     }
0119 
0120     bool empty() const
0121     {
0122         return begin() == end();
0123     }
0124 
0125     template<typename ContainerType>
0126     ContainerType toContainer(ContainerType &&c = {})
0127     {
0128         for (auto e : *this)
0129             c.push_back(e);
0130         return std::forward<ContainerType>(c);
0131     }
0132 
0133 private:
0134     const ArrayType &data;
0135     char s;
0136 };