Home | History | Annotate | Download | only in core
      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 *
     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
     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:
     62          vector() : p(NULL), n(0) {
     63          }
     64 
     65          vector(const vector &v) : p(alloc(v.n, v.p, v.n)), n(v.n) {
     66          }
     67 
     68          vector(T *p, size_t n) : p(alloc(n, p, n)), n(n) {
     69          }
     70 
     71          template<typename C>
     72          vector(const C &v) :
     73             p(alloc(v.size(), &*v.begin(), v.size())), n(v.size()) {
     74          }
     75 
     76          ~vector() {
     77             free(n, p);
     78          }
     79 
     80          vector &
     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
     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
    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
    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
    119          size() const {
    120             return n;
    121          }
    122 
    123          T *
    124          begin() {
    125             return p;
    126          }
    127 
    128          const T *
    129          begin() const {
    130             return p;
    131          }
    132 
    133          T *
    134          end() {
    135             return p + n;
    136          }
    137 
    138          const T *
    139          end() const {
    140             return p + n;
    141          }
    142 
    143          T &
    144          operator[](int i) {
    145             return p[i];
    146          }
    147 
    148          const T &
    149          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:
    161          vector_ref(T *p, size_t n) : p(p), n(n) {
    162          }
    163 
    164          template<typename C>
    165          vector_ref(C &v) : p(&*v.begin()), n(v.size()) {
    166          }
    167 
    168          size_t
    169          size() const {
    170             return n;
    171          }
    172 
    173          T *
    174          begin() {
    175             return p;
    176          }
    177 
    178          const T *
    179          begin() const {
    180             return p;
    181          }
    182 
    183          T *
    184          end() {
    185             return p + n;
    186          }
    187 
    188          const T *
    189          end() const {
    190             return p + n;
    191          }
    192 
    193          T &
    194          operator[](int i) {
    195             return p[i];
    196          }
    197 
    198          const T &
    199          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:
    214             virtual ~error() {}
    215          };
    216 
    217          istream(const buffer_t &buf) : buf(buf), offset(0) {}
    218 
    219          void
    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 
    237          ostream(buffer_t &buf) : buf(buf), offset(buf.size()) {}
    238 
    239          void
    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:
    253          string(const char *p) : vector_ref(p, std::strlen(p)) {
    254          }
    255 
    256          template<typename C>
    257          string(const C &v) : vector_ref(v) {
    258          }
    259 
    260          operator std::string() const {
    261             return std::string(begin(), end());
    262          }
    263 
    264          const char *
    265          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
    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