Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-21 10:00:34

0001 /***********************************************************************************\
0002 * (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations *
0003 *                                                                                   *
0004 * This software is distributed under the terms of the Apache version 2 licence,     *
0005 * copied verbatim in the file "LICENSE".                                            *
0006 *                                                                                   *
0007 * In applying this licence, CERN does not waive the privileges and immunities       *
0008 * granted to it by virtue of its status as an Intergovernmental Organization        *
0009 * or submit itself to any jurisdiction.                                             *
0010 \***********************************************************************************/
0011 #ifndef GAUDIKERNEL_REVERSE_H
0012 #define GAUDIKERNEL_REVERSE_H
0013 //
0014 // provide a generic 'reverse' function for use in range-based for loops.
0015 //
0016 // example:
0017 //
0018 //      #include "GaudiKernel/reverse.h"
0019 //      auto l = { 1,2,3,4 };
0020 //      for ( const auto& i : reverse( l ) ) std::cout << i << std::endl;
0021 //
0022 //  Note that it is perfectly fine to reverse a temporary. The temporary
0023 //  will be moved into the reverse_wrapper, and thus kept alive for the
0024 //  duration of the loop. In case reverse is called on an lvalue, the wrapper
0025 //  will take a reference, so no copy will be performed. (if you wonder how
0026 //  the code below (very implicitly) distinguishes between the two cases,
0027 //  google for 'C++11 reference collapsing' -- short version: C++ does not
0028 //  allow references to references, so in cases where this would happen,
0029 //  one gets an lvalue reference)
0030 //
0031 //  Also note that reverse_wrapper does not have a constructor, but this
0032 //  implies that it does meet the requirements for aggregate initializaton,
0033 //  which allows for {} initialization of its member.
0034 //
0035 
0036 #include <iterator>
0037 #include <utility>
0038 
0039 namespace details {
0040 
0041   template <typename Iterable>
0042   struct reverse_wrapper {
0043     Iterable iterable;
0044   };
0045 
0046   template <typename T>
0047   auto begin( reverse_wrapper<T>& w ) {
0048     using std::rbegin;
0049     return rbegin( w.iterable );
0050   }
0051   template <typename T>
0052   auto end( reverse_wrapper<T>& w ) {
0053     using std::rend;
0054     return rend( w.iterable );
0055   }
0056 } // namespace details
0057 
0058 template <typename T>
0059 ::details::reverse_wrapper<T> reverse( T&& iterable ) {
0060   return { std::forward<T>( iterable ) };
0061 }
0062 
0063 #endif