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 __CL_UTIL_HPP__
  24. #define __CL_UTIL_HPP__
  25.  
  26. #include <cstdint>
  27. #include <cstring>
  28. #include <algorithm>
  29. #include <map>
  30.  
  31. #include "core/base.hpp"
  32. #include "pipe/p_compiler.h"
  33.  
  34. namespace clover {
  35.    ///
  36.    /// Return a matrix (a container of containers) in \a buf with
  37.    /// argument and bounds checking.  Intended to be used by
  38.    /// implementations of \a clGetXXXInfo().
  39.    ///
  40.    template<typename T, typename V>
  41.    cl_int
  42.    matrix_property(void *buf, size_t size, size_t *size_ret, const V& v) {
  43.       if (buf && size < sizeof(T *) * v.size())
  44.          return CL_INVALID_VALUE;
  45.  
  46.       if (size_ret)
  47.          *size_ret = sizeof(T *) * v.size();
  48.  
  49.       if (buf)
  50.          for_each([](typename V::value_type src, T *dst) {
  51.                if (dst)
  52.                   std::copy(src.begin(), src.end(), dst);
  53.             },
  54.             v.begin(), v.end(), (T **)buf);
  55.  
  56.       return CL_SUCCESS;
  57.    }
  58.  
  59.    ///
  60.    /// Return a vector in \a buf with argument and bounds checking.
  61.    /// Intended to be used by implementations of \a clGetXXXInfo().
  62.    ///
  63.    template<typename T, typename V>
  64.    cl_int
  65.    vector_property(void *buf, size_t size, size_t *size_ret, const V& v) {
  66.       if (buf && size < sizeof(T) * v.size())
  67.          return CL_INVALID_VALUE;
  68.  
  69.       if (size_ret)
  70.          *size_ret = sizeof(T) * v.size();
  71.       if (buf)
  72.          std::copy(v.begin(), v.end(), (T *)buf);
  73.  
  74.       return CL_SUCCESS;
  75.    }
  76.  
  77.    ///
  78.    /// Return a scalar in \a buf with argument and bounds checking.
  79.    /// Intended to be used by implementations of \a clGetXXXInfo().
  80.    ///
  81.    template<typename T>
  82.    cl_int
  83.    scalar_property(void *buf, size_t size, size_t *size_ret, T v) {
  84.       return vector_property<T>(buf, size, size_ret, std::vector<T>(1, v));
  85.    }
  86.  
  87.    ///
  88.    /// Return a string in \a buf with argument and bounds checking.
  89.    /// Intended to be used by implementations of \a clGetXXXInfo().
  90.    ///
  91.    inline cl_int
  92.    string_property(void *buf, size_t size, size_t *size_ret,
  93.                    const std::string &v) {
  94.       if (buf && size < v.size() + 1)
  95.          return CL_INVALID_VALUE;
  96.  
  97.       if (size_ret)
  98.          *size_ret = v.size() + 1;
  99.       if (buf)
  100.          std::strcpy((char *)buf, v.c_str());
  101.  
  102.       return CL_SUCCESS;
  103.    }
  104.  
  105.    ///
  106.    /// Convert a NULL-terminated property list into an std::map.
  107.    ///
  108.    template<typename T>
  109.    std::map<T, T>
  110.    property_map(const T *props) {
  111.       std::map<T, T> m;
  112.  
  113.       while (props && *props) {
  114.          T key = *props++;
  115.          T value = *props++;
  116.  
  117.          if (m.count(key))
  118.             throw clover::error(CL_INVALID_PROPERTY);
  119.  
  120.          m.insert({ key, value });
  121.       }
  122.  
  123.       return m;
  124.    }
  125.  
  126.    ///
  127.    /// Convert an std::map into a NULL-terminated property list.
  128.    ///
  129.    template<typename T>
  130.    std::vector<T>
  131.    property_vector(const std::map<T, T> &m) {
  132.       std::vector<T> v;
  133.  
  134.       for (auto &p : m) {
  135.          v.push_back(p.first);
  136.          v.push_back(p.second);
  137.       }
  138.  
  139.       v.push_back(0);
  140.       return v;
  141.    }
  142.  
  143.    ///
  144.    /// Return an error code in \a p if non-zero.
  145.    ///
  146.    inline void
  147.    ret_error(cl_int *p, const clover::error &e) {
  148.       if (p)
  149.          *p = e.get();
  150.    }
  151.  
  152.    ///
  153.    /// Return a reference-counted object in \a p if non-zero.
  154.    /// Otherwise release object ownership.
  155.    ///
  156.    template<typename T, typename S>
  157.    void
  158.    ret_object(T p, S v) {
  159.       if (p)
  160.          *p = v;
  161.       else
  162.          v->release();
  163.    }
  164. }
  165.  
  166. #endif
  167.