Path: blob/21.2-virgl/src/gallium/frontends/clover/core/property.hpp
4572 views
//1// Copyright 2013 Francisco Jerez2//3// Permission is hereby granted, free of charge, to any person obtaining a4// copy of this software and associated documentation files (the "Software"),5// to deal in the Software without restriction, including without limitation6// the rights to use, copy, modify, merge, publish, distribute, sublicense,7// and/or sell copies of the Software, and to permit persons to whom the8// Software is furnished to do so, subject to the following conditions:9//10// The above copyright notice and this permission notice shall be included in11// all copies or substantial portions of the Software.12//13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL16// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR17// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,18// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR19// OTHER DEALINGS IN THE SOFTWARE.20//2122#ifndef CLOVER_CORE_PROPERTY_HPP23#define CLOVER_CORE_PROPERTY_HPP2425#include <map>2627#include "util/range.hpp"28#include "util/algorithm.hpp"2930namespace clover {31class property_buffer;3233namespace detail {34template<typename T>35class property_scalar {36public:37property_scalar(property_buffer &buf) : buf(buf) {38}3940inline property_scalar &41operator=(const T &x);4243private:44property_buffer &buf;45};4647template<typename T>48class property_vector {49public:50property_vector(property_buffer &buf) : buf(buf) {51}5253template<typename S>54inline property_vector &55operator=(const S &v);5657private:58property_buffer &buf;59};6061template<typename T>62class property_matrix {63public:64property_matrix(property_buffer &buf) : buf(buf) {65}6667template<typename S>68inline property_matrix &69operator=(const S &v);7071private:72property_buffer &buf;73};7475class property_string {76public:77property_string(property_buffer &buf) : buf(buf) {78}7980inline property_string &81operator=(const std::string &v);8283private:84property_buffer &buf;85};86};8788///89/// Return value buffer used by the CL property query functions.90///91class property_buffer {92public:93property_buffer(void *r_buf, size_t size, size_t *r_size) :94r_buf(r_buf), size(size), r_size(r_size) {95}9697template<typename T>98detail::property_scalar<T>99as_scalar() {100return { *this };101}102103template<typename T>104detail::property_vector<T>105as_vector() {106return { *this };107}108109template<typename T>110detail::property_matrix<T>111as_matrix() {112return { *this };113}114115detail::property_string116as_string() {117return { *this };118}119120template<typename T>121iterator_range<T *>122allocate(size_t n) {123if (r_buf && size < n * sizeof(T))124throw error(CL_INVALID_VALUE);125126if (r_size)127*r_size = n * sizeof(T);128129if (r_buf)130return range((T *)r_buf, n);131else132return { };133}134135private:136void *const r_buf;137const size_t size;138size_t *const r_size;139};140141namespace detail {142template<typename T>143inline property_scalar<T> &144property_scalar<T>::operator=(const T &x) {145auto r = buf.allocate<T>(1);146147if (!r.empty())148r.front() = x;149150return *this;151}152153template<typename T>154template<typename S>155inline property_vector<T> &156property_vector<T>::operator=(const S &v) {157auto r = buf.allocate<T>(v.size());158159if (!r.empty())160copy(v, r.begin());161162return *this;163}164165template<typename T>166template<typename S>167inline property_matrix<T> &168property_matrix<T>::operator=(const S &v) {169auto r = buf.allocate<T *>(v.size());170171if (!r.empty())172for_each([](typename S::value_type src, T *dst) {173if (dst)174copy(src, dst);175}, v, r);176177return *this;178}179180inline property_string &181property_string::operator=(const std::string &v) {182auto r = buf.allocate<char>(v.size() + 1);183184if (!r.empty())185copy(range(v.begin(), r.size()), r.begin());186187return *this;188}189};190191template<typename T>192class property_element {193public:194property_element() : x() {195}196197property_element(T x) : x(x) {198}199200template<typename S>201typename std::enable_if<!std::is_convertible<T, S>::value, S>::type202as() const {203static_assert(sizeof(S) <= sizeof(T), "Ensure type fits in property list");204return reinterpret_cast<S>(x);205}206207template<typename S>208typename std::enable_if<std::is_convertible<T, S>::value, S>::type209as() const {210return static_cast<S>(x);211}212213private:214T x;215};216217template<typename D>218using property_list = std::map<D, property_element<D>>;219220struct property_list_tag;221222///223/// Create a clover::property_list object from a zero-terminated224/// CL property list.225///226template<typename T, typename D,227typename = typename std::enable_if<228std::is_same<T, property_list_tag>::value>::type>229property_list<D>230obj(const D *d_props) {231property_list<D> props;232233while (d_props && *d_props) {234auto key = *d_props++;235auto value = *d_props++;236237if (props.count(key))238throw error(CL_INVALID_PROPERTY);239240props.insert({ key, value });241}242243return props;244}245246///247/// Create a zero-terminated CL property list from a248/// clover::property_list object.249///250template<typename D>251std::vector<D>252desc(const property_list<D> &props) {253std::vector<D> d_props;254255for (auto &prop : props) {256d_props.push_back(prop.first);257d_props.push_back(prop.second.template as<D>());258}259260d_props.push_back(0);261262return d_props;263}264}265266#endif267268269