LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
makeValueIndex.h
Go to the documentation of this file.
1 
13 #ifndef LARCOREALG_COREUTILS_MAKEVALUEINDEX_H
14 #define LARCOREALG_COREUTILS_MAKEVALUEINDEX_H
15 
16 // LArSoft libraries
19 #include "larcorealg/CoreUtils/fromFutureImport.h" // util::pre_std::identity<>
20 
21 // C/C++ standard library
22 #include <cstddef> // std::size_t
23 #include <map>
24 #include <stdexcept> // std::runtime_error
25 #include <string> // std::to_string()
26 #include <type_traits> // std::invoke_result_t, std::remove_reference_t
27 
28 namespace util {
29 
55  template <typename Coll, typename Extractor>
56  decltype(auto) makeValueIndex(Coll const& coll, Extractor getter);
57 
58  template <typename Coll>
59  auto makeValueIndex(Coll const& coll)
60  {
62  }
63 
64 } // namespace util
65 
66 //------------------------------------------------------------------------------
67 //--- template implementation
68 //------------------------------------------------------------------------------
69 template <typename Coll, typename Extractor>
70 decltype(auto) util::makeValueIndex(Coll const& coll, Extractor getter)
71 {
72 
73  using Value_t = typename Coll::value_type;
74  using Key_t
75 #if 0 // this is C++17...
76  = std::remove_reference_t<std::invoke_result_t<Extractor, Value_t>>;
77 #else // ... and this is what Clang 5.0 understands:
78  = std::remove_reference_t<decltype(getter(std::declval<Value_t>()))>;
79 #endif // 0
80 
81  using Map_t = std::map<Key_t, std::size_t>;
82 
83  Map_t index;
84  for (auto&& [iValue, collValue] : util::enumerate(coll)) {
85 
86  Key_t const& key = getter(collValue);
87  auto const iKey = index.lower_bound(key);
88  if ((iKey != index.end()) && (iKey->first == key)) {
89  // no guarantee that `key` supports `std::to_string()`: print only indices
90  throw std::runtime_error(std::string(__func__) + ": element #" + std::to_string(iValue) +
91  " has the same key as #" + std::to_string(iKey->second));
92  }
93  index.emplace_hint(iKey, key, iValue);
94  } // for
95 
96  return index;
97 
98 } // util::makeValueIndex()
99 
100 //------------------------------------------------------------------------------
101 
102 #endif // LARCOREALG_COREUTILS_MAKEVALUEINDEX_H
Namespace for general, non-LArSoft-specific utilities.
Definition: PIDAAlg.h:26
Definition of util::enumerate().
auto enumerate(Iterables &&...iterables)
Range-for loop helper tracking the number of iteration.
Definition: enumerate.h:65
decltype(auto) constexpr to_string(T &&obj)
ADL-aware version of std::to_string.
Transparent functor that returns its argument just as passed.
Functions to help debugging by instrumenting code.
decltype(auto) makeValueIndex(Coll const &coll, Extractor getter)
Returns a map of value to index.
Code that might appear as standard C++ in the future.