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