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     // For API compatibility with SkString's reset (vs. std:string's clear)
     86     void reset();
     87     // For API compatibility with SkString's findLastOf(vs. find_last_of -> size_t)
     88     int findLastOf(const char c) const;
     89 #endif
     90     void vappendf(const char* fmt, va_list va);
     91 
     92     bool startsWith(const char* s) const;
     93     bool endsWith(const char* s) const;
     94 
     95     int find(const char* substring, int fromPos = 0) const;
     96     int find(const String& substring, int fromPos = 0) const;
     97 
     98     String operator+(const char* s) const;
     99     String operator+(const String& s) const;
    100     String operator+(StringFragment s) const;
    101     String& operator+=(char c);
    102     String& operator+=(const char* s);
    103     String& operator+=(const String& s);
    104     String& operator+=(StringFragment s);
    105     bool operator==(const char* s) const;
    106     bool operator!=(const char* s) const;
    107     bool operator==(const String& s) const;
    108     bool operator!=(const String& s) const;
    109     friend String operator+(const char* s1, const String& s2);
    110     friend bool operator==(const char* s1, const String& s2);
    111     friend bool operator!=(const char* s1, const String& s2);
    112 
    113 private:
    114     typedef SKSL_STRING_BASE INHERITED;
    115 };
    116 
    117 String operator+(const char* s1, const String& s2);
    118 bool operator!=(const char* s1, const String& s2);
    119 
    120 String to_string(double value);
    121 
    122 String to_string(int32_t value);
    123 
    124 String to_string(uint32_t value);
    125 
    126 String to_string(int64_t value);
    127 
    128 String to_string(uint64_t value);
    129 
    130 int stoi(const String& s);
    131 
    132 double stod(const String& s);
    133 
    134 long stol(const String& s);
    135 
    136 } // namespace
    137 
    138 namespace std {
    139     template<> struct hash<SkSL::StringFragment> {
    140         size_t operator()(const SkSL::StringFragment& s) const {
    141             size_t result = 0;
    142             for (size_t i = 0; i < s.fLength; ++i) {
    143                 result = result * 101 + s.fChars[i];
    144             }
    145             return result;
    146         }
    147     };
    148 } // namespace
    149 
    150 #ifdef SKSL_USE_STD_STRING
    151 namespace std {
    152     template<> struct hash<SkSL::String> {
    153         size_t operator()(const SkSL::String& s) const {
    154             return hash<std::string>{}(s);
    155         }
    156     };
    157 } // namespace
    158 #else
    159 #include "SkOpts.h"
    160 namespace std {
    161     template<> struct hash<SkSL::String> {
    162         size_t operator()(const SkSL::String& s) const {
    163             return SkOpts::hash_fn(s.c_str(), s.size(), 0);
    164         }
    165     };
    166 } // namespace
    167 #endif // SKIA_STANDALONE
    168 
    169 #endif
    170