1 // Copyright 2021 The Tint Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef SRC_UTILS_REVERSE_H_ 16 #define SRC_UTILS_REVERSE_H_ 17 18 #include <iterator> 19 20 namespace tint { 21 namespace utils { 22 23 namespace detail { 24 /// Used by utils::Reverse to hold the underlying iterable. 25 /// begin(ReverseIterable<T>) and end(ReverseIterable<T>) are automatically 26 /// called for range-for loops, via argument-dependent lookup. 27 /// See https://en.cppreference.com/w/cpp/language/range-for 28 template <typename T> 29 struct ReverseIterable { 30 /// The wrapped iterable object. 31 T& iterable; 32 }; 33 34 template <typename T> begin(ReverseIterable<T> r_it)35auto begin(ReverseIterable<T> r_it) { 36 return std::rbegin(r_it.iterable); 37 } 38 39 template <typename T> end(ReverseIterable<T> r_it)40auto end(ReverseIterable<T> r_it) { 41 return std::rend(r_it.iterable); 42 } 43 } // namespace detail 44 45 /// Reverse returns an iterable wrapper that when used in range-for loops, 46 /// performs a reverse iteration over the object `iterable`. 47 /// Example: 48 /// ``` 49 /// /* Equivalent to: 50 /// * for (auto it = vec.rbegin(); i != vec.rend(); ++it) { 51 /// * auto v = *it; 52 /// */ 53 /// for (auto v : utils::Reverse(vec)) { 54 /// } 55 /// ``` 56 template <typename T> Reverse(T && iterable)57detail::ReverseIterable<T> Reverse(T&& iterable) { 58 return {iterable}; 59 } 60 61 } // namespace utils 62 } // namespace tint 63 64 #endif // SRC_UTILS_REVERSE_H_ 65