Home | History | Annotate | Download | only in sksl
      1 /*
      2  * Copyright 2017 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #ifndef SKSL_STRING
      9 #define SKSL_STRING
     10 
     11 #include <cstring>
     12 
     13 #define SKSL_USE_STD_STRING
     14 
     15 #include <stdarg.h>
     16 
     17 #ifdef SKSL_USE_STD_STRING
     18     #define SKSL_STRING_BASE std::string
     19     #include <string>
     20 #else
     21     #define SKSL_STRING_BASE SkString
     22     #include "SkString.h"
     23 #endif
     24 
     25 namespace SkSL {
     26 
     27 // Represents a (not necessarily null-terminated) slice of a string.
     28 struct StringFragment {
     29     StringFragment()
     30     : fChars("")
     31     , fLength(0) {}
     32 
     33     StringFragment(const char* chars)
     34     : fChars(chars)
     35     , fLength(strlen(chars)) {}
     36 
     37     StringFragment(const char* chars, size_t length)
     38     : fChars(chars)
     39     , fLength(length) {}
     40 
     41     char operator[](size_t idx) const {
     42         return fChars[idx];
     43     }
     44 
     45     bool operator==(const char* s) const;
     46     bool operator!=(const char* s) const;
     47     bool operator==(StringFragment s) const;
     48     bool operator!=(StringFragment s) const;
     49     bool operator<(StringFragment s) const;
     50 
     51     const char* fChars;
     52     size_t fLength;
     53 };
     54 
     55 bool operator==(const char* s1, StringFragment s2);
     56 
     57 bool operator!=(const char* s1, StringFragment s2);
     58 
     59 class String : public SKSL_STRING_BASE {
     60 public:
     61     String() = default;
     62     String(const String&) = default;
     63     String(String&&) = default;
     64     String& operator=(const String&) = default;
     65     String& operator=(String&&) = default;
     66 
     67 #ifndef SKSL_USE_STD_STRING
     68     String(const SkString& s)
     69     : INHERITED(s) {}
     70 #endif
     71 
     72     String(const char* s)
     73     : INHERITED(s) {}
     74 
     75     String(const char* s, size_t size)
     76     : INHERITED(s, size) {}
     77 
     78     String(StringFragment s)
     79     : INHERITED(s.fChars, s.fLength) {}
     80 
     81     static String printf(const char* fmt, ...);
     82 
     83 #ifdef SKSL_USE_STD_STRING
     84     void appendf(const char* fmt, ...);
     85 #endif
     86     void vappendf(const char* fmt, va_list va);
     87 
     88     bool startsWith(const char* s) const;
     89     bool endsWith(const char* s) const;
     90 
     91     String operator+(const char* s) const;
     92     String operator+(const String& s) const;
     93     String operator+(StringFragment s) const;
     94     String& operator+=(char c);
     95     String& operator+=(const char* s);
     96     String& operator+=(const String& s);
     97     String& operator+=(StringFragment s);
     98     bool operator==(const char* s) const;
     99     bool operator!=(const char* s) const;
    100     bool operator==(const String& s) const;
    101     bool operator!=(const String& s) const;
    102     friend String operator+(const char* s1, const String& s2);
    103     friend bool operator==(const char* s1, const String& s2);
    104     friend bool operator!=(const char* s1, const String& s2);
    105 
    106 private:
    107     typedef SKSL_STRING_BASE INHERITED;
    108 };
    109 
    110 String operator+(const char* s1, const String& s2);
    111 bool operator!=(const char* s1, const String& s2);
    112 
    113 String to_string(double value);
    114 
    115 String to_string(int32_t value);
    116 
    117 String to_string(uint32_t value);
    118 
    119 String to_string(int64_t value);
    120 
    121 String to_string(uint64_t value);
    122 
    123 int stoi(const String& s);
    124 
    125 double stod(const String& s);
    126 
    127 long stol(const String& s);
    128 
    129 } // namespace
    130 
    131 namespace std {
    132     template<> struct hash<SkSL::StringFragment> {
    133         size_t operator()(const SkSL::StringFragment& s) const {
    134             size_t result = 0;
    135             for (size_t i = 0; i < s.fLength; ++i) {
    136                 result = result * 101 + s.fChars[i];
    137             }
    138             return result;
    139         }
    140     };
    141 } // namespace
    142 
    143 #ifdef SKSL_USE_STD_STRING
    144 namespace std {
    145     template<> struct hash<SkSL::String> {
    146         size_t operator()(const SkSL::String& s) const {
    147             return hash<std::string>{}(s);
    148         }
    149     };
    150 } // namespace
    151 #else
    152 #include "SkOpts.h"
    153 namespace std {
    154     template<> struct hash<SkSL::String> {
    155         size_t operator()(const SkSL::String& s) const {
    156             return SkOpts::hash_fn(s.c_str(), s.size(), 0);
    157         }
    158     };
    159 } // namespace
    160 #endif // SKIA_STANDALONE
    161 
    162 #endif
    163