diff dep/toml11/toml/string.hpp @ 318:3b355fa948c7

config: use TOML instead of INI unfortunately, INI is not enough, and causes some paths including semicolons to break with our current storage of the library folders. so, I decided to switch to TOML which does support real arrays...
author Paper <paper@paper.us.eu.org>
date Wed, 12 Jun 2024 05:25:41 -0400
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dep/toml11/toml/string.hpp	Wed Jun 12 05:25:41 2024 -0400
@@ -0,0 +1,228 @@
+//     Copyright Toru Niina 2017.
+// Distributed under the MIT License.
+#ifndef TOML11_STRING_HPP
+#define TOML11_STRING_HPP
+
+#include "version.hpp"
+
+#include <cstdint>
+
+#include <algorithm>
+#include <string>
+
+#if TOML11_CPLUSPLUS_STANDARD_VERSION >= 201703L
+#if __has_include(<string_view>)
+#define TOML11_USING_STRING_VIEW 1
+#include <string_view>
+#endif
+#endif
+
+namespace toml
+{
+
+enum class string_t : std::uint8_t
+{
+    basic   = 0,
+    literal = 1,
+};
+
+struct string
+{
+    string()  = default;
+    ~string() = default;
+    string(const string& s) = default;
+    string(string&& s)      = default;
+    string& operator=(const string& s) = default;
+    string& operator=(string&& s)      = default;
+
+    string(const std::string& s): kind(string_t::basic), str(s){}
+    string(const std::string& s, string_t k):   kind(k), str(s){}
+    string(const char* s):        kind(string_t::basic), str(s){}
+    string(const char* s,        string_t k):   kind(k), str(s){}
+
+    string(std::string&& s): kind(string_t::basic), str(std::move(s)){}
+    string(std::string&& s, string_t k):   kind(k), str(std::move(s)){}
+
+    string& operator=(const std::string& s)
+    {kind = string_t::basic; str = s; return *this;}
+    string& operator=(std::string&& s)
+    {kind = string_t::basic; str = std::move(s); return *this;}
+
+    operator std::string&       () &      noexcept {return str;}
+    operator std::string const& () const& noexcept {return str;}
+    operator std::string&&      () &&     noexcept {return std::move(str);}
+
+    string& operator+=(const char*        rhs) {str += rhs; return *this;}
+    string& operator+=(const char         rhs) {str += rhs; return *this;}
+    string& operator+=(const std::string& rhs) {str += rhs; return *this;}
+    string& operator+=(const string&      rhs) {str += rhs.str; return *this;}
+
+#if defined(TOML11_USING_STRING_VIEW) && TOML11_USING_STRING_VIEW>0
+    explicit string(std::string_view s): kind(string_t::basic), str(s){}
+    string(std::string_view s, string_t k): kind(k), str(s){}
+
+    string& operator=(std::string_view s)
+    {kind = string_t::basic; str = s; return *this;}
+
+    explicit operator std::string_view() const noexcept
+    {return std::string_view(str);}
+
+    string& operator+=(const std::string_view& rhs) {str += rhs; return *this;}
+#endif
+
+    string_t    kind;
+    std::string str;
+};
+
+inline bool operator==(const string& lhs, const string& rhs)
+{
+    return lhs.kind == rhs.kind && lhs.str == rhs.str;
+}
+inline bool operator!=(const string& lhs, const string& rhs)
+{
+    return !(lhs == rhs);
+}
+inline bool operator<(const string& lhs, const string& rhs)
+{
+    return (lhs.kind == rhs.kind) ? (lhs.str < rhs.str) : (lhs.kind < rhs.kind);
+}
+inline bool operator>(const string& lhs, const string& rhs)
+{
+    return rhs < lhs;
+}
+inline bool operator<=(const string& lhs, const string& rhs)
+{
+    return !(rhs < lhs);
+}
+inline bool operator>=(const string& lhs, const string& rhs)
+{
+    return !(lhs < rhs);
+}
+
+inline bool
+operator==(const string& lhs, const std::string& rhs) {return lhs.str == rhs;}
+inline bool
+operator!=(const string& lhs, const std::string& rhs) {return lhs.str != rhs;}
+inline bool
+operator< (const string& lhs, const std::string& rhs) {return lhs.str <  rhs;}
+inline bool
+operator> (const string& lhs, const std::string& rhs) {return lhs.str >  rhs;}
+inline bool
+operator<=(const string& lhs, const std::string& rhs) {return lhs.str <= rhs;}
+inline bool
+operator>=(const string& lhs, const std::string& rhs) {return lhs.str >= rhs;}
+
+inline bool
+operator==(const std::string& lhs, const string& rhs) {return lhs == rhs.str;}
+inline bool
+operator!=(const std::string& lhs, const string& rhs) {return lhs != rhs.str;}
+inline bool
+operator< (const std::string& lhs, const string& rhs) {return lhs <  rhs.str;}
+inline bool
+operator> (const std::string& lhs, const string& rhs) {return lhs >  rhs.str;}
+inline bool
+operator<=(const std::string& lhs, const string& rhs) {return lhs <= rhs.str;}
+inline bool
+operator>=(const std::string& lhs, const string& rhs) {return lhs >= rhs.str;}
+
+inline bool
+operator==(const string& lhs, const char* rhs) {return lhs.str == std::string(rhs);}
+inline bool
+operator!=(const string& lhs, const char* rhs) {return lhs.str != std::string(rhs);}
+inline bool
+operator< (const string& lhs, const char* rhs) {return lhs.str <  std::string(rhs);}
+inline bool
+operator> (const string& lhs, const char* rhs) {return lhs.str >  std::string(rhs);}
+inline bool
+operator<=(const string& lhs, const char* rhs) {return lhs.str <= std::string(rhs);}
+inline bool
+operator>=(const string& lhs, const char* rhs) {return lhs.str >= std::string(rhs);}
+
+inline bool
+operator==(const char* lhs, const string& rhs) {return std::string(lhs) == rhs.str;}
+inline bool
+operator!=(const char* lhs, const string& rhs) {return std::string(lhs) != rhs.str;}
+inline bool
+operator< (const char* lhs, const string& rhs) {return std::string(lhs) <  rhs.str;}
+inline bool
+operator> (const char* lhs, const string& rhs) {return std::string(lhs) >  rhs.str;}
+inline bool
+operator<=(const char* lhs, const string& rhs) {return std::string(lhs) <= rhs.str;}
+inline bool
+operator>=(const char* lhs, const string& rhs) {return std::string(lhs) >= rhs.str;}
+
+template<typename charT, typename traits>
+std::basic_ostream<charT, traits>&
+operator<<(std::basic_ostream<charT, traits>& os, const string& s)
+{
+    if(s.kind == string_t::basic)
+    {
+        if(std::find(s.str.cbegin(), s.str.cend(), '\n') != s.str.cend())
+        {
+            // it contains newline. make it multiline string.
+            os << "\"\"\"\n";
+            for(auto i=s.str.cbegin(), e=s.str.cend(); i!=e; ++i)
+            {
+                switch(*i)
+                {
+                    case '\\': {os << "\\\\"; break;}
+                    case '\"': {os << "\\\""; break;}
+                    case '\b': {os << "\\b";  break;}
+                    case '\t': {os << "\\t";  break;}
+                    case '\f': {os << "\\f";  break;}
+                    case '\n': {os << '\n';   break;}
+                    case '\r':
+                    {
+                        // since it is a multiline string,
+                        // CRLF is not needed to be escaped.
+                        if(std::next(i) != e && *std::next(i) == '\n')
+                        {
+                            os << "\r\n";
+                            ++i;
+                        }
+                        else
+                        {
+                            os << "\\r";
+                        }
+                        break;
+                    }
+                    default: {os << *i; break;}
+                }
+            }
+            os << "\\\n\"\"\"";
+            return os;
+        }
+        // no newline. make it inline.
+        os << "\"";
+        for(const auto c : s.str)
+        {
+            switch(c)
+            {
+                case '\\': {os << "\\\\"; break;}
+                case '\"': {os << "\\\""; break;}
+                case '\b': {os << "\\b";  break;}
+                case '\t': {os << "\\t";  break;}
+                case '\f': {os << "\\f";  break;}
+                case '\n': {os << "\\n";  break;}
+                case '\r': {os << "\\r";  break;}
+                default  : {os << c;      break;}
+            }
+        }
+        os << "\"";
+        return os;
+    }
+    // the string `s` is literal-string.
+    if(std::find(s.str.cbegin(), s.str.cend(), '\n') != s.str.cend() ||
+       std::find(s.str.cbegin(), s.str.cend(), '\'') != s.str.cend() )
+    {
+        // contains newline or single quote. make it multiline.
+        os << "'''\n" << s.str << "'''";
+        return os;
+    }
+    // normal literal string
+    os << '\'' << s.str << '\'';
+    return os;
+}
+
+} // toml
+#endif// TOML11_STRING_H