1c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// 2c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// Copyright 2012 Francisco Jerez 3c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// 4c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// Permission is hereby granted, free of charge, to any person obtaining a 5c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// copy of this software and associated documentation files (the "Software"), 6c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// to deal in the Software without restriction, including without limitation 7c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// the rights to use, copy, modify, merge, publish, distribute, sublicense, 8c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// and/or sell copies of the Software, and to permit persons to whom the 9c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// Software is furnished to do so, subject to the following conditions: 10c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// 11c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// The above copyright notice and this permission notice shall be included in 12c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// all copies or substantial portions of the Software. 13c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// 14c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 18c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 19c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// SOFTWARE. 21c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez// 22c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 23c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez#ifndef __CL_UTIL_HPP__ 24c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez#define __CL_UTIL_HPP__ 25c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 26c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez#include <cstdint> 27c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez#include <cstring> 28c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez#include <algorithm> 29c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez#include <map> 30c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 31c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez#include "core/base.hpp" 32c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez#include "pipe/p_compiler.h" 33c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 34c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jereznamespace clover { 35c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// 36c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// Return a matrix (a container of containers) in \a buf with 37c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// argument and bounds checking. Intended to be used by 38c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// implementations of \a clGetXXXInfo(). 39c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// 40c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez template<typename T, typename V> 41c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez cl_int 42c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez matrix_property(void *buf, size_t size, size_t *size_ret, const V& v) { 43c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez if (buf && size < sizeof(T *) * v.size()) 44c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez return CL_INVALID_VALUE; 45c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 46c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez if (size_ret) 47c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez *size_ret = sizeof(T *) * v.size(); 48c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 49c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez if (buf) 50c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez for_each([](typename V::value_type src, T *dst) { 51c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez if (dst) 52c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez std::copy(src.begin(), src.end(), dst); 53c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez }, 54c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez v.begin(), v.end(), (T **)buf); 55c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 56c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez return CL_SUCCESS; 57c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez } 58c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 59c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// 60c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// Return a vector in \a buf with argument and bounds checking. 61c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// Intended to be used by implementations of \a clGetXXXInfo(). 62c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// 63c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez template<typename T, typename V> 64c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez cl_int 65c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez vector_property(void *buf, size_t size, size_t *size_ret, const V& v) { 66c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez if (buf && size < sizeof(T) * v.size()) 67c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez return CL_INVALID_VALUE; 68c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 69c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez if (size_ret) 70c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez *size_ret = sizeof(T) * v.size(); 71c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez if (buf) 72c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez std::copy(v.begin(), v.end(), (T *)buf); 73c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 74c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez return CL_SUCCESS; 75c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez } 76c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 77c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// 78c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// Return a scalar in \a buf with argument and bounds checking. 79c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// Intended to be used by implementations of \a clGetXXXInfo(). 80c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// 81c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez template<typename T> 82c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez cl_int 83c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez scalar_property(void *buf, size_t size, size_t *size_ret, T v) { 84c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez return vector_property<T>(buf, size, size_ret, std::vector<T>(1, v)); 85c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez } 86c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 87c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// 88c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// Return a string in \a buf with argument and bounds checking. 89c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// Intended to be used by implementations of \a clGetXXXInfo(). 90c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// 91c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez inline cl_int 92c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez string_property(void *buf, size_t size, size_t *size_ret, 93c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez const std::string &v) { 94c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez if (buf && size < v.size() + 1) 95c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez return CL_INVALID_VALUE; 96c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 97c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez if (size_ret) 98c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez *size_ret = v.size() + 1; 99c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez if (buf) 100c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez std::strcpy((char *)buf, v.c_str()); 101c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 102c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez return CL_SUCCESS; 103c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez } 104c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 105c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// 106c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// Convert a NULL-terminated property list into an std::map. 107c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// 108c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez template<typename T> 109c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez std::map<T, T> 110c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez property_map(const T *props) { 111c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez std::map<T, T> m; 112c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 113c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez while (props && *props) { 114c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez T key = *props++; 115c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez T value = *props++; 116c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 117c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez if (m.count(key)) 118c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez throw clover::error(CL_INVALID_PROPERTY); 119c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 120c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez m.insert({ key, value }); 121c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez } 122c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 123c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez return m; 124c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez } 125c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 126c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// 127c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// Convert an std::map into a NULL-terminated property list. 128c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// 129c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez template<typename T> 130c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez std::vector<T> 131c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez property_vector(const std::map<T, T> &m) { 132c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez std::vector<T> v; 133c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 134c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez for (auto &p : m) { 135c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez v.push_back(p.first); 136c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez v.push_back(p.second); 137c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez } 138c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 139c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez v.push_back(0); 140c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez return v; 141c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez } 142c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 143c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// 144c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// Return an error code in \a p if non-zero. 145c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// 146c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez inline void 147c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez ret_error(cl_int *p, const clover::error &e) { 148c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez if (p) 149c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez *p = e.get(); 150c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez } 151c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 152c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// 153c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// Return a reference-counted object in \a p if non-zero. 154c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// Otherwise release object ownership. 155c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez /// 156c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez template<typename T, typename S> 157c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez void 158c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez ret_object(T p, S v) { 159c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez if (p) 160c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez *p = v; 161c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez else 162c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez v->release(); 163c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez } 164c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez} 165c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez 166c6db1b3396384186aab5b685fe1fd540e17b3a62Francisco Jerez#endif 167