1 //
2 // Copyright 2012 Francisco Jerez
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a
5 // copy of this software and associated documentation files (the "Software"),
6 // to deal in the Software without restriction, including without limitation
7 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 // and/or sell copies of the Software, and to permit persons to whom the
9 // Software is furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17 // THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19 // OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20 // SOFTWARE.
21 //
22 
23 #ifndef __CORE_COMPAT_HPP__
24 #define __CORE_COMPAT_HPP__
25 
26 #include <new>
27 #include <cstring>
28 #include <cstdlib>
29 #include <string>
30 #include <stdint.h>
31 
32 
33 namespace clover {
34    namespace compat {
35       // XXX - For cases where we can't rely on STL...  I.e. the
36       //       interface between code compiled as C++98 and C++11
37       //       source.  Get rid of this as soon as everything can be
38       //       compiled as C++11.
39 
40       template<typename T>
41       class vector {
42       protected:
43          static T *
alloc(int n,const T * q,int m)44          alloc(int n, const T *q, int m) {
45             T *p = reinterpret_cast<T *>(std::malloc(n * sizeof(T)));
46 
47             for (int i = 0; i < m; ++i)
48                new(&p[i]) T(q[i]);
49 
50             return p;
51          }
52 
53          static void
free(int n,T * p)54          free(int n, T *p) {
55             for (int i = 0; i < n; ++i)
56                p[i].~T();
57 
58             std::free(p);
59          }
60 
61       public:
vector()62          vector() : p(NULL), n(0) {
63          }
64 
vector(const vector & v)65          vector(const vector &v) : p(alloc(v.n, v.p, v.n)), n(v.n) {
66          }
67 
vector(T * p,size_t n)68          vector(T *p, size_t n) : p(alloc(n, p, n)), n(n) {
69          }
70 
71          template<typename C>
vector(const C & v)72          vector(const C &v) :
73             p(alloc(v.size(), &*v.begin(), v.size())), n(v.size()) {
74          }
75 
~vector()76          ~vector() {
77             free(n, p);
78          }
79 
80          vector &
operator =(const vector & v)81          operator=(const vector &v) {
82             free(n, p);
83 
84             p = alloc(v.n, v.p, v.n);
85             n = v.n;
86 
87             return *this;
88          }
89 
90          void
reserve(size_t m)91          reserve(size_t m) {
92             if (n < m) {
93                T *q = alloc(m, p, n);
94                free(n, p);
95 
96                p = q;
97                n = m;
98             }
99          }
100 
101          void
resize(size_t m,T x=T ())102          resize(size_t m, T x = T()) {
103             size_t n = size();
104 
105             reserve(m);
106 
107             for (size_t i = n; i < m; ++i)
108                new(&p[i]) T(x);
109          }
110 
111          void
push_back(const T & x)112          push_back(const T &x) {
113             size_t n = size();
114             reserve(n + 1);
115             new(&p[n]) T(x);
116          }
117 
118          size_t
size() const119          size() const {
120             return n;
121          }
122 
123          T *
begin()124          begin() {
125             return p;
126          }
127 
128          const T *
begin() const129          begin() const {
130             return p;
131          }
132 
133          T *
end()134          end() {
135             return p + n;
136          }
137 
138          const T *
end() const139          end() const {
140             return p + n;
141          }
142 
143          T &
operator [](int i)144          operator[](int i) {
145             return p[i];
146          }
147 
148          const T &
operator [](int i) const149          operator[](int i) const {
150             return p[i];
151          }
152 
153       private:
154          T *p;
155          size_t n;
156       };
157 
158       template<typename T>
159       class vector_ref {
160       public:
vector_ref(T * p,size_t n)161          vector_ref(T *p, size_t n) : p(p), n(n) {
162          }
163 
164          template<typename C>
vector_ref(C & v)165          vector_ref(C &v) : p(&*v.begin()), n(v.size()) {
166          }
167 
168          size_t
size() const169          size() const {
170             return n;
171          }
172 
173          T *
begin()174          begin() {
175             return p;
176          }
177 
178          const T *
begin() const179          begin() const {
180             return p;
181          }
182 
183          T *
end()184          end() {
185             return p + n;
186          }
187 
188          const T *
end() const189          end() const {
190             return p + n;
191          }
192 
193          T &
operator [](int i)194          operator[](int i) {
195             return p[i];
196          }
197 
198          const T &
operator [](int i) const199          operator[](int i) const {
200             return p[i];
201          }
202 
203       private:
204          T *p;
205          size_t n;
206       };
207 
208       class istream {
209       public:
210          typedef vector_ref<const unsigned char> buffer_t;
211 
212          class error {
213          public:
~error()214             virtual ~error() {}
215          };
216 
istream(const buffer_t & buf)217          istream(const buffer_t &buf) : buf(buf), offset(0) {}
218 
219          void
read(char * p,size_t n)220          read(char *p, size_t n) {
221             if (offset + n > buf.size())
222                throw error();
223 
224             std::memcpy(p, buf.begin() + offset, n);
225             offset += n;
226          }
227 
228       private:
229          const buffer_t &buf;
230          size_t offset;
231       };
232 
233       class ostream {
234       public:
235          typedef vector<unsigned char> buffer_t;
236 
ostream(buffer_t & buf)237          ostream(buffer_t &buf) : buf(buf), offset(buf.size()) {}
238 
239          void
write(const char * p,size_t n)240          write(const char *p, size_t n) {
241             buf.resize(offset + n);
242             std::memcpy(buf.begin() + offset, p, n);
243             offset += n;
244          }
245 
246       private:
247          buffer_t &buf;
248          size_t offset;
249       };
250 
251       class string : public vector_ref<const char> {
252       public:
string(const char * p)253          string(const char *p) : vector_ref(p, std::strlen(p)) {
254          }
255 
256          template<typename C>
string(const C & v)257          string(const C &v) : vector_ref(v) {
258          }
259 
operator std::string() const260          operator std::string() const {
261             return std::string(begin(), end());
262          }
263 
264          const char *
find(const string & s) const265          find(const string &s) const {
266             for (size_t i = 0; i + s.size() < size(); ++i) {
267                if (!std::memcmp(begin() + i, s.begin(), s.size()))
268                   return begin() + i;
269             }
270 
271             return end();
272          }
273       };
274 
275       template<typename T>
276       bool
operator ==(const vector_ref<T> & a,const vector_ref<T> & b)277       operator==(const vector_ref<T> &a, const vector_ref<T> &b) {
278          if (a.size() != b.size())
279             return false;
280 
281          for (size_t i = 0; i < a.size(); ++i)
282             if (a[i] != b[i])
283                return false;
284 
285          return true;
286       }
287    }
288 }
289 
290 #endif
291