values.h
Go to the documentation of this file.
1 /**
2  * @file larcorealg/CoreUtils/values.h
3  * @brief Definition of `util::values()` and `util::const_values()`.
4  * @author Gianluca Petrillo (petrillo@slac.stanford.edu)
5  * @date May 8, 2019
6  *
7  * This is a header-only library.
8  */
9 
10 #ifndef LARCOREALG_COREUTILS_VALUES_H
11 #define LARCOREALG_COREUTILS_VALUES_H
12 
13 
14 // LArSoft libraries
15 #include "larcorealg/CoreUtils/span.h" // util::make_transformed_span()
17 
18 // C/C++ libraries
19 #include <map>
20 #include <unordered_map>
21 #include <utility> // std::forward(), std::as_const()
22 #include <tuple> // std::get()
23 #include <type_traits>
24 #include <cstddef> // std::size_t
25 
26 
27 namespace util {
28 
29 
30  // -- BEGIN -- Transformed iterations ----------------------------------------
31  /// @name Transformed iterations
32  /// @{
33 
34  /**
35  * @brief Range-for loop helper iterating across the values of the specified
36  * collection.
37  * @tparam Coll type of the collection to iterate through
38  * @param coll the collection to iterate through
39  * @return an object suitable for range-for loop
40  * @see `util::const_values()`
41  *
42  * This function is in most of cases a no-operation, returning the collection
43  * just as it was specified, to be iterated on directly.
44  * In case of mapping types, though, a different object is returned and the
45  * iteration will happen to the value type of the mapping instead than on
46  * the key-value pair.
47  *
48  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
49  * std::map<int, float> data { { 1, 4.0F }, { 3, 12.0F }, { 2, 8.0F } };
50  * std::vector<float> values;
51  *
52  * for (float value: util::values(data))
53  * values.push_back(value);
54  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
55  * will result in `values` vector being of size `3` and with values
56  * `{ 4.0F, 8.0F, 12.0F }` (the order is the one of iterating through a
57  * `std::map`).
58  *
59  */
60  template <typename Coll>
61  decltype(auto) values(Coll&& coll);
62 
63  /**
64  * @brief Range-for loop helper iterating across the constant values of the
65  * specified collection.
66  * @see `util::values()`
67  *
68  * This function is equivalent to `util::values()` but the values are
69  * extracted as if the specified collection were constant.
70  */
71  template <typename Coll>
72  decltype(auto) const_values(Coll&& coll);
73 
74 
75  /// @}
76  // -- END -- Transformed iterations ------------------------------------------
77 
78 
79 } // namespace util
80 
81 
82 //==============================================================================
83 //=== template implementation
84 //==============================================================================
85 //------------------------------------------------------------------------------
86 //--- util::values()
87 //------------------------------------------------------------------------------
88 namespace util::details {
89 
90  //----------------------------------------------------------------------------
91  template <typename Coll, typename = void>
92  struct values_impl {
93 
94  template <typename T>
95  static constexpr decltype(auto) iterate(T&& coll) noexcept
96  { return coll; }
97 
98  }; // struct values_impl
99 
100 
101  //----------------------------------------------------------------------------
102  template <typename Map, std::size_t NElement = 1U>
104 
105  template <typename T>
106  static constexpr decltype(auto) iterate(T&& coll) noexcept
107  { return util::get_elements<NElement>(std::forward<T>(coll)); }
108 
109  }; // map_values_impl
110 
111 
112  //----------------------------------------------------------------------------
113  template <typename Key, typename Value, typename... Args>
114  struct values_impl<std::map<Key, Value, Args...>>
115  : map_values_impl<std::map<Key, Value, Args...>>
116  {};
117  template <typename Key, typename Value, typename... Args>
118  struct values_impl<std::unordered_map<Key, Value, Args...>>
119  : map_values_impl<std::unordered_map<Key, Value, Args...>>
120  {};
121 
122 
123  //----------------------------------------------------------------------------
124 
125 } // namespace util::details
126 
127 
128 //------------------------------------------------------------------------------
129 template <typename Coll>
130 decltype(auto) util::values(Coll&& coll) {
132  (std::forward<Coll>(coll));
133 } // util::values()
134 
135 
136 //------------------------------------------------------------------------------
137 template <typename Coll>
138 decltype(auto) util::const_values(Coll&& coll)
139  { return values(std::as_const(coll)); }
140 
141 
142 //------------------------------------------------------------------------------
143 
144 
145 #endif // LARCOREALG_COREUTILS_VALUES_H
Namespace for general, non-LArSoft-specific utilities.
An object with a begin and end iterator.
Definition of util::get_elements() and util::get_const_elements().
decltype(auto) const_values(Coll &&coll)
Range-for loop helper iterating across the constant values of the specified collection.
STL namespace.
decltype(auto) values(Coll &&coll)
Range-for loop helper iterating across the values of the specified collection.