Path: blob/21.2-virgl/src/gallium/frontends/clover/util/algebra.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_UTIL_ALGEBRA_HPP23#define CLOVER_UTIL_ALGEBRA_HPP2425#include <type_traits>2627#include "util/range.hpp"28#include "util/functional.hpp"2930namespace clover {31///32/// Class that identifies vectors (in the linear-algebraic sense).33///34/// There should be a definition of this class for each type that35/// makes sense as vector arithmetic operand.36///37template<typename V, typename = void>38struct vector_traits;3940///41/// References of vectors are vectors.42///43template<typename T>44struct vector_traits<T &, typename vector_traits<T>::enable> {45typedef void enable;46};4748///49/// Constant vectors are vectors.50///51template<typename T>52struct vector_traits<const T, typename vector_traits<T>::enable> {53typedef void enable;54};5556///57/// Arrays of arithmetic types are vectors.58///59template<typename T, std::size_t N>60struct vector_traits<std::array<T, N>,61typename std::enable_if<62std::is_arithmetic<T>::value>::type> {63typedef void enable;64};6566namespace detail {67template<typename... Ts>68struct are_defined {69typedef void enable;70};71}7273///74/// The result of mapping a vector is a vector.75///76template<typename F, typename... Vs>77struct vector_traits<adaptor_range<F, Vs...>,78typename detail::are_defined<79typename vector_traits<Vs>::enable...>::enable> {80typedef void enable;81};8283///84/// Vector sum.85///86template<typename U, typename V,87typename = typename vector_traits<U>::enable,88typename = typename vector_traits<V>::enable>89adaptor_range<plus, U, V>90operator+(U &&u, V &&v) {91return map(plus(), std::forward<U>(u), std::forward<V>(v));92}9394///95/// Vector difference.96///97template<typename U, typename V,98typename = typename vector_traits<U>::enable,99typename = typename vector_traits<V>::enable>100adaptor_range<minus, U, V>101operator-(U &&u, V &&v) {102return map(minus(), std::forward<U>(u), std::forward<V>(v));103}104105///106/// Scalar multiplication.107///108template<typename U, typename T,109typename = typename vector_traits<U>::enable>110adaptor_range<multiplies_by_t<T>, U>111operator*(U &&u, T &&a) {112return map(multiplies_by<T>(std::forward<T>(a)), std::forward<U>(u));113}114115///116/// Scalar multiplication.117///118template<typename U, typename T,119typename = typename vector_traits<U>::enable>120adaptor_range<multiplies_by_t<T>, U>121operator*(T &&a, U &&u) {122return map(multiplies_by<T>(std::forward<T>(a)), std::forward<U>(u));123}124125///126/// Additive inverse.127///128template<typename U,129typename = typename vector_traits<U>::enable>130adaptor_range<negate, U>131operator-(U &&u) {132return map(negate(), std::forward<U>(u));133}134135namespace detail {136template<typename U, typename V>137using dot_type = typename std::common_type<138typename std::remove_reference<U>::type::value_type,139typename std::remove_reference<V>::type::value_type140>::type;141}142143///144/// Dot product of two vectors.145///146/// It can also do matrix multiplication if \a u or \a v is a147/// vector of vectors.148///149template<typename U, typename V,150typename = typename vector_traits<U>::enable,151typename = typename vector_traits<V>::enable>152detail::dot_type<U, V>153dot(U &&u, V &&v) {154return fold(plus(), detail::dot_type<U, V>(),155map(multiplies(), u, v));156}157}158159#endif160161162