Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:11:12

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 #include <tuple>
0012 
0013 namespace Acts {
0014 
0015 /// Function that allows to zip some ranges to be used in a range-based for
0016 /// loop. When wanting to mutate the entries, the result must be captured by
0017 /// value:
0018 ///
0019 /// for(auto [a, b, c] : zip(ra, rb, rc)) { a+=2; }
0020 ///
0021 /// @tparam R The ranges type pack
0022 /// @param r The ranges parameter pack
0023 /// @note the behaviour is undefined if the ranges do not have equal range
0024 template <typename... R>
0025 auto zip(R &&...r) {
0026   struct It {
0027     std::tuple<decltype(r.begin())...> iterators;
0028     static_assert(std::tuple_size_v<decltype(iterators)> > 0);
0029 
0030     using reference = std::tuple<decltype(*r.begin())...>;
0031 
0032     auto operator++() {
0033       std::apply([](auto &...args) { (++args, ...); }, iterators);
0034       return *this;
0035     }
0036 
0037     auto operator!=(const It &other) const {
0038       return std::get<0>(iterators) != std::get<0>(other.iterators);
0039     }
0040 
0041     reference operator*() {
0042       return std::apply([](auto &...args) { return reference{*args...}; },
0043                         iterators);
0044     }
0045   };
0046 
0047   struct Zip {
0048     It b, e;
0049 
0050     auto begin() { return b; }
0051     auto end() { return e; }
0052   };
0053 
0054   auto begin = std::make_tuple(r.begin()...);
0055   auto end = std::make_tuple(r.end()...);
0056   return Zip{It{begin}, It{end}};
0057 }
0058 
0059 }  // namespace Acts