Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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 OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18. // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19. // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20. // OTHER DEALINGS IN THE 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.