source: trunk/src/lol/base/string.h @ 2851

Last change on this file since 2851 was 2851, checked in by sam, 6 years ago

base: allow String::C() to be non-const.

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Id
File size: 5.2 KB
Line 
1//
2// Lol Engine
3//
4// Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net>
5//   This program is free software; you can redistribute it and/or
6//   modify it under the terms of the Do What The Fuck You Want To
7//   Public License, Version 2, as published by Sam Hocevar. See
8//   http://www.wtfpl.net/ for more details.
9//
10
11//
12// The String class
13// ----------------
14// A very simple String class, based on Array.
15//
16
17#if !defined __LOL_BASE_STRING_H__
18#define __LOL_BASE_STRING_H__
19
20#include <lol/base/assert.h>
21#include <lol/base/array.h>
22
23#include <cstring>
24#include <cstdarg>
25
26namespace lol
27{
28
29class String : protected Array<char>
30{
31private:
32    typedef Array<char> Super;
33
34public:
35    inline String()
36      : Super()
37    {
38        Push('\0');
39    }
40
41    inline String(char const *str)
42      : Super()
43    {
44        using namespace std;
45        ASSERT(str);
46        Resize((int)strlen(str));
47        memcpy(&(*this)[0], str, Count() + 1);
48    }
49
50    inline String(char const *str, int count)
51      : Super()
52    {
53        using namespace std;
54        ASSERT(str);
55        Resize(count);
56        memcpy(&(*this)[0], str, count);
57        ((Super &)*this)[count] = '\0';
58    }
59
60    inline String(String const &s)
61      : Super((Super const &)s)
62    {
63    }
64
65    inline char &operator [](int n)
66    {
67        /* Allow n == Count() because we might have reasonable reasons
68         * to access that hidden null character. */
69        ASSERT(n >= 0);
70        ASSERT((unsigned)n <= (unsigned)Count());
71        return ((Super &)*this)[n];
72    }
73
74    inline char const &operator [](int n) const
75    {
76        ASSERT(n >= 0);
77        ASSERT(n <= Count());
78        return ((Super const &)*this)[n];
79    }
80
81    inline char &Last()
82    {
83        ASSERT(Count() > 0);
84        return (*this)[Count() - 1];
85    }
86
87    inline char const &Last() const
88    {
89        ASSERT(Count() > 0);
90        return (*this)[Count() - 1];
91    }
92
93    inline int Count() const
94    {
95        return ((Super const &)*this).Count() - 1;
96    }
97
98    /* Return a C string */
99    inline char const *C() const
100    {
101        return &(*this)[0];
102    }
103
104    /* Non-const version; make sure to not overflow the internal array */
105    inline char *C()
106    {
107        return &(*this)[0];
108    }
109
110    /* Does not initialise the newly allocated characters */
111    void Resize(int count)
112    {
113        ASSERT(count >= 0);
114        ((Super &)*this).Resize(count + 1);
115        ((Super &)*this).Last() = '\0';
116    }
117
118    String Sub(int start, int count) const
119    {
120        ASSERT(start >= 0);
121        ASSERT(count >= 0);
122        ASSERT(start + count <= Count());
123        return String(&(*this)[start], count);
124    }
125
126    int IndexOf(char token) const
127    {
128        using namespace std;
129
130        char const *tmp = strchr(C(), token);
131        return tmp ? (int)(intptr_t)(tmp - C()) : -1;
132    }
133
134    int IndexOf(char const* token) const
135    {
136        using namespace std;
137
138        char const *tmp = strstr(C(), token);
139        return tmp ? (int)(intptr_t)(tmp - C()) : -1;
140    }
141
142    int LastIndexOf(char token) const
143    {
144        using namespace std;
145
146        char const *tmp = strrchr(C(), token);
147        return tmp ? (int)(intptr_t)(tmp - C()) : -1;
148    }
149
150    int LastIndexOf(char const* token) const
151    {
152        using namespace std;
153
154        int token_len = (int)strlen(token);
155        for (int i = Count() - token_len; i >= 0; --i)
156            if (strstr(C() + i, token))
157                return i;
158        return -1;
159    }
160
161    inline String operator +(String const &s) const
162    {
163        String ret(*this);
164        return ret += s;
165    }
166
167    inline String& operator +=(String const &s)
168    {
169        using namespace std;
170        int old_count = Count();
171        Resize(Count() + s.Count());
172        memcpy(&(*this)[old_count], &s[0], Count() - old_count);
173        return *this;
174    }
175
176    inline String operator +(char c) const
177    {
178        String ret(*this);
179        return ret += c;
180    }
181
182    inline String& operator +=(char c)
183    {
184        ((Super &)*this).Last() = c;
185        ((Super &)*this).Push('\0');
186        return *this;
187    }
188
189    inline bool operator ==(String const &s) const
190    {
191        using namespace std;
192        return Count() == s.Count()
193                && memcmp(C(), s.C(), Count()) == 0;
194    }
195
196    inline bool operator !=(String const &s) const
197    {
198        return !(*this == s);
199    }
200
201    inline bool operator ==(char const* sz) const
202    {
203        /* We parse the C string twice because of strlen + memcmp
204         * but it's probably still faster than doing it by hand. */
205        using namespace std;
206        int sz_len = (int)strlen(sz);
207        return Count() == sz_len
208                && memcmp(C(), sz, sz_len) == 0;
209    }
210
211    inline bool operator !=(char const* sz) const
212    {
213        return !(*this == sz);
214    }
215
216#ifdef __GNUC__
217#   define LOL_FMT_ATTR(n, p) __attribute__((format(printf, n, p)))
218#else
219#   define LOL_FMT_ATTR(n, p)
220#endif
221    static String Printf(char const *format, ...) LOL_FMT_ATTR(1, 2);
222#undef LOL_FMT_ATTR
223    static String Printf(char const *format, va_list ap);
224};
225
226inline bool operator ==(char const* sz, String const &s)
227{
228    return s == sz;
229}
230
231inline bool operator !=(char const* sz, String const &s)
232{
233    return s != sz;
234}
235
236} /* namespace lol */
237
238#endif // __LOL_BASE_STRING_H__
239
Note: See TracBrowser for help on using the repository browser.