Path: blob/21.2-virgl/src/gallium/frontends/clover/util/tuple.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_TUPLE_HPP23#define CLOVER_UTIL_TUPLE_HPP2425#include <tuple>2627namespace clover {28namespace tuple {29///30/// Static sequence of integers.31///32template<int... Is>33struct integral_sequence;3435///36/// Static sequence containing all integers from 0 to N-1.37///38template<int N, int... Is>39struct enumerate {40typedef typename enumerate<N-1, N-1, Is...>::type41type;42};4344template<int... Is>45struct enumerate<0, Is...> {46typedef integral_sequence<Is...> type;47};4849namespace detail {50template<typename F, typename T,51typename E = typename enumerate<std::tuple_size<52typename std::remove_reference<T>::type>::value53>::type>54struct _apply;5556template<typename F, typename T, int... Is>57struct _apply<F, T, integral_sequence<Is...>> {58typedef typename std::remove_reference<F>::type func_type;59typedef decltype(60std::declval<func_type>()(std::get<Is>(std::declval<T &&>())...)61) value_type;6263static value_type64eval(F &&f, T &&t) {65return f(std::get<Is>(std::forward<T>(t))...);66}67};68}6970///71/// Evaluate function \a f with the elements of tuple \a t72/// expanded as arguments.73///74template<typename F, typename T>75typename detail::_apply<F, T>::value_type76apply(F &&f, T &&t) {77return detail::_apply<F, T>::eval(std::forward<F>(f),78std::forward<T>(t));79}8081namespace detail {82template<typename F, typename T,83typename E = typename enumerate<std::tuple_size<84typename std::remove_reference<T>::type>::value85>::type>86struct _map;8788template<typename F, typename T, int... Is>89struct _map<F, T, integral_sequence<Is...>> {90typedef typename std::remove_reference<F>::type func_type;91typedef std::tuple<92decltype(std::declval<func_type>()(93std::get<Is>(std::declval<T &&>())))...94> value_type;9596static value_type97eval(F &&f, T &&t) {98return value_type(f(std::get<Is>(std::forward<T>(t)))...);99}100};101}102103///104/// Evaluate function \a f on each element of the tuple \a t and105/// return the resulting values as a new tuple.106///107template<typename F, typename T>108typename detail::_map<F, T>::value_type109map(F &&f, T &&t) {110return detail::_map<F, T>::eval(std::forward<F>(f),111std::forward<T>(t));112}113}114}115116#endif117118119