Path: blob/21.2-virgl/src/gallium/frontends/clover/util/adaptor.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_ADAPTOR_HPP23#define CLOVER_UTIL_ADAPTOR_HPP2425#include <iterator>2627#include "util/tuple.hpp"28#include "util/pointer.hpp"29#include "util/functional.hpp"3031namespace clover {32namespace detail {33///34/// Implementation of the iterator concept that transforms the35/// value of the source iterators \a Is on dereference by use of36/// a functor \a F.37///38/// The exact category of the resulting iterator should be the39/// least common denominator of the source iterator categories.40///41template<typename F, typename... Is>42class iterator_adaptor {43public:44typedef std::forward_iterator_tag iterator_category;45typedef typename std::result_of<46F(typename std::iterator_traits<Is>::reference...)47>::type reference;48typedef typename std::remove_reference<reference>::type value_type;49typedef pseudo_ptr<value_type> pointer;50typedef std::ptrdiff_t difference_type;5152iterator_adaptor() {53}5455iterator_adaptor(F f, std::tuple<Is...> &&its) :56f(f), its(std::move(its)) {57}5859reference60operator*() const {61return tuple::apply(f, tuple::map(derefs(), its));62}6364iterator_adaptor &65operator++() {66tuple::map(preincs(), its);67return *this;68}6970iterator_adaptor71operator++(int) {72auto jt = *this;73++*this;74return jt;75}7677bool78operator==(const iterator_adaptor &jt) const {79return its == jt.its;80}8182bool83operator!=(const iterator_adaptor &jt) const {84return its != jt.its;85}8687pointer88operator->() const {89return { **this };90}9192iterator_adaptor &93operator--() {94tuple::map(predecs(), its);95return *this;96}9798iterator_adaptor99operator--(int) {100auto jt = *this;101--*this;102return jt;103}104105iterator_adaptor &106operator+=(difference_type n) {107tuple::map(advances_by(n), its);108return *this;109}110111iterator_adaptor &112operator-=(difference_type n) {113tuple::map(advances_by(-n), its);114return *this;115}116117iterator_adaptor118operator+(difference_type n) const {119auto jt = *this;120jt += n;121return jt;122}123124iterator_adaptor125operator-(difference_type n) const {126auto jt = *this;127jt -= n;128return jt;129}130131difference_type132operator-(const iterator_adaptor &jt) const {133return std::get<0>(its) - std::get<0>(jt.its);134}135136reference137operator[](difference_type n) const {138return *(*this + n);139}140141bool142operator<(iterator_adaptor &jt) const {143return *this - jt < 0;144}145146bool147operator>(iterator_adaptor &jt) const {148return *this - jt > 0;149}150151bool152operator>=(iterator_adaptor &jt) const {153return !(*this < jt);154}155156bool157operator<=(iterator_adaptor &jt) const {158return !(*this > jt);159}160161protected:162F f;163std::tuple<Is...> its;164};165166template<typename F, typename... Is>167iterator_adaptor<F, Is...>168operator+(typename iterator_adaptor<F, Is...>::difference_type n,169const iterator_adaptor<F, Is...> &jt) {170return (jt + n);171}172173template<typename F, typename... Is>174iterator_adaptor<F, Is...>175operator-(typename iterator_adaptor<F, Is...>::difference_type n,176const iterator_adaptor<F, Is...> &jt) {177return (jt - n);178}179}180}181182#endif183184185