blob: b3e411eca9f7d0956b4d2829f30f30baf406d036 [file] [log] [blame]
Ethan Nicholas0df1b042017-03-31 13:56:23 -04001/*
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
Ethan Nicholas5b5f0962017-09-11 13:50:14 -070011#include <cstring>
12
Brian Osman93ba0a42017-08-14 14:48:10 -040013#define SKSL_USE_STD_STRING
Ethan Nicholas0df1b042017-03-31 13:56:23 -040014
Roger Johannessonb5f3b652017-09-11 15:42:09 +020015#include <stdarg.h>
16
Brian Osman93ba0a42017-08-14 14:48:10 -040017#ifdef SKSL_USE_STD_STRING
Ethan Nicholas0df1b042017-03-31 13:56:23 -040018 #define SKSL_STRING_BASE std::string
19 #include <string>
20#else
21 #define SKSL_STRING_BASE SkString
22 #include "SkString.h"
23#endif
24
25namespace SkSL {
26
Ethan Nicholas5b5f0962017-09-11 13:50:14 -070027// Represents a (not necessarily null-terminated) slice of a string.
28struct StringFragment {
29 StringFragment()
Ethan Nicholasd608c092017-10-26 09:30:08 -040030 : fChars("")
Ethan Nicholas5b5f0962017-09-11 13:50:14 -070031 , 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;
Ethan Nicholas2c33e3e2018-01-08 15:36:28 -050049 bool operator<(StringFragment s) const;
Ethan Nicholas5b5f0962017-09-11 13:50:14 -070050
51 const char* fChars;
52 size_t fLength;
53};
54
Ethan Nicholascc305772017-10-13 16:17:45 -040055bool operator==(const char* s1, StringFragment s2);
56
57bool operator!=(const char* s1, StringFragment s2);
58
Ethan Nicholas0df1b042017-03-31 13:56:23 -040059class String : public SKSL_STRING_BASE {
60public:
61 String() = default;
62 String(const String&) = default;
63 String(String&&) = default;
64 String& operator=(const String&) = default;
65 String& operator=(String&&) = default;
66
Brian Osman93ba0a42017-08-14 14:48:10 -040067#ifndef SKSL_USE_STD_STRING
Ethan Nicholas0df1b042017-03-31 13:56:23 -040068 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
Ethan Nicholas5b5f0962017-09-11 13:50:14 -070078 String(StringFragment s)
79 : INHERITED(s.fChars, s.fLength) {}
80
Ethan Nicholas0df1b042017-03-31 13:56:23 -040081 static String printf(const char* fmt, ...);
82
Brian Osman93ba0a42017-08-14 14:48:10 -040083#ifdef SKSL_USE_STD_STRING
Ethan Nicholas0df1b042017-03-31 13:56:23 -040084 void appendf(const char* fmt, ...);
Michael Ludwige84fb192018-08-21 16:32:20 -040085 // 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;
Ethan Nicholas0df1b042017-03-31 13:56:23 -040089#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
Michael Ludwiga4275592018-08-31 10:52:47 -040095 int find(const char* substring, int fromPos = 0) const;
96 int find(const String& substring, int fromPos = 0) const;
97
Ethan Nicholas0df1b042017-03-31 13:56:23 -040098 String operator+(const char* s) const;
99 String operator+(const String& s) const;
Ethan Nicholas5b5f0962017-09-11 13:50:14 -0700100 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);
Ethan Nicholas0df1b042017-03-31 13:56:23 -0400105 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
113private:
114 typedef SKSL_STRING_BASE INHERITED;
115};
116
117String operator+(const char* s1, const String& s2);
118bool operator!=(const char* s1, const String& s2);
119
120String to_string(double value);
121
122String to_string(int32_t value);
123
124String to_string(uint32_t value);
125
126String to_string(int64_t value);
127
128String to_string(uint64_t value);
129
Brian Osman634624a2017-08-15 11:14:30 -0400130int stoi(const String& s);
Ethan Nicholas0df1b042017-03-31 13:56:23 -0400131
Brian Osman634624a2017-08-15 11:14:30 -0400132double stod(const String& s);
Ethan Nicholas0df1b042017-03-31 13:56:23 -0400133
Brian Osman634624a2017-08-15 11:14:30 -0400134long stol(const String& s);
Ethan Nicholas0df1b042017-03-31 13:56:23 -0400135
136} // namespace
137
Ethan Nicholas5b5f0962017-09-11 13:50:14 -0700138namespace 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
Brian Osman93ba0a42017-08-14 14:48:10 -0400150#ifdef SKSL_USE_STD_STRING
Ethan Nicholas0df1b042017-03-31 13:56:23 -0400151namespace 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"
160namespace 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