| The Gaudi Framework v29r0 (ff2e7097)

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

reverse.h
Go to the documentation of this file.
1 #ifndef GAUDIKERNEL_REVERSE_H
2 #define GAUDIKERNEL_REVERSE_H
3 //
4 // provide a generic 'reverse' function for use in range-based for loops.
5 //
6 // example:
7 //
8 // #include "GaudiKernel/reverse.h"
9 // auto l = { 1,2,3,4 };
10 // for ( const auto& i : reverse( l ) ) std::cout << i << std::endl;
11 //
12 // Note that it is perfectly fine to reverse a temporary. The temporary
13 // will be moved into the reverse_wrapper, and thus kept alive for the
14 // duration of the loop. In case reverse is called on an lvalue, the wrapper
15 // will take a reference, so no copy will be performed. (if you wonder how
16 // the code below (very implicitly) distinguishes between the two cases,
17 // google for 'C++11 reference collapsing' -- short version: C++ does not
18 // allow references to references, so in cases where this would happen,
19 // one gets an lvalue reference)
20 //
21 // Also note that reverse_wrapper does not have a constructor, but this
22 // implies that it does meet the requirements for aggregate initializaton,
23 // which allows for {} initialization of its member.
24 //
25 #include <utility>
26
27 #include <utility>
28
29 template <typename Iterable>
30 struct reverse_wrapper {
31 Iterable iterable;
32 };
33
34 template <typename T>
35 reverse_wrapper<T> reverse( T&& iterable )
36 {
37 return {std::forward<T>( iterable )};
38 }
39
40 #if defined __GNUC__ && __GNUC__ < 5
41
42 // std::rbegin and std::rend require gcc 5.0 or later (or clang 3.5 or later)
43 template <typename T>
44 auto begin( reverse_wrapper<T>& w ) -> decltype( w.iterable.rbegin() )
45 {
46 return w.iterable.rbegin();
47 }
48 template <typename T>
49 auto end( reverse_wrapper<T>& w ) -> decltype( w.iterable.rend() )
50 {
51 return w.iterable.rend();
52 }
53
54 #else
55
56 #include <iterator>
57 template <typename T>
58 auto begin( reverse_wrapper<T>& w )
59 {
60 using std::rbegin;
61 return rbegin( w.iterable );
62 }
63 template <typename T>
64 auto end( reverse_wrapper<T>& w )
65 {
66 using std::rend;
67 return rend( w.iterable );
68 }
69
70 #endif
71
72 #endif
reverse_wrapper::iterable
Iterable iterable
Definition: reverse.h:31
begin
auto begin(reverse_wrapper< T > &w)
Definition: reverse.h:58
end
auto end(reverse_wrapper< T > &w)
Definition: reverse.h:64
reverse_wrapper
Definition: reverse.h:30
reverse
reverse_wrapper< T > reverse(T &&iterable)
Definition: reverse.h:35