LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
ParameterSetImplHelpers.cc
Go to the documentation of this file.
2 #include "boost/algorithm/string.hpp"
3 #include "cetlib/container_algorithms.h"
4 #include "cetlib/split_by_regex.h"
5 #include "fhiclcpp/coding.h"
6 #include "fhiclcpp/exception.h"
7 
8 #include <algorithm>
9 #include <regex>
10 
11 namespace {
12  std::regex const reBrackets{R"((\]\[|\[|\]))"};
13 }
14 
15 namespace fhicl::detail {
16 
17  //===============================================================
18  // get_names
19 
20  Keys::Keys(std::vector<std::string> const& keys, std::string const& last)
21  : tables_{keys}, last_{last}
22  {}
23  Keys::~Keys() = default;
24 
25  std::vector<std::string> const&
26  Keys::tables() const noexcept
27  {
28  return tables_;
29  }
30 
31  std::string const&
32  Keys::last() const noexcept
33  {
34  return last_;
35  }
36 
37  Keys
38  get_names(std::string const& key)
39  {
40  std::vector<std::string> keys;
41  boost::algorithm::split(keys, key, boost::algorithm::is_any_of("."));
42 
43  // Remove empty keys
44  keys.erase(std::remove(keys.begin(), keys.end(), ""), keys.end());
45 
46  if (keys.empty())
47  throw fhicl::exception(fhicl::cant_find, "vacuous key");
48 
49  std::string const last = keys.back();
50  keys.pop_back();
51 
52  return Keys{keys, last};
53  }
54 
55  //===============================================================
56  // get_sequence_indices
57 
58  SequenceKey::SequenceKey(std::string const& name,
59  std::vector<std::size_t> const& indices)
60  : name_{name}, indices_{indices}
61  {}
62 
63  SequenceKey::~SequenceKey() = default;
64 
65  std::string const&
66  SequenceKey::name() const noexcept
67  {
68  return name_;
69  }
70 
71  std::vector<std::size_t> const&
72  SequenceKey::indices() const noexcept
73  {
74  return indices_;
75  }
76 
78  get_sequence_indices(std::string const& key)
79  {
80  // Split "name[0][5][1]" according to delimiters "][", "[", and "]"
81  // to give {"name","0","5","1"};
82  auto tokens = cet::split_by_regex(key, reBrackets);
83 
84  auto const name = tokens.front();
85  tokens.erase(tokens.begin());
86 
87  std::vector<std::size_t> indices;
88  cet::transform_all(
89  tokens, std::back_inserter(indices), [](std::string const& index) {
90  return std::stoul(index);
91  });
92  return SequenceKey{name, indices};
93  }
94 
95  bool
98  std::any& a)
99  {
100  if (it == cend) {
101  // If we got this far, that means the element must exist,
102  // otherwise the previous recursive 'find_parameter' call would
103  // have returned false.
104  return true;
105  }
106 
107  auto seq = std::any_cast<ps_sequence_t>(a);
108  if (*it >= seq.size())
109  return false;
110 
111  a = std::move(seq[*it]);
112 
113  return find_an_any(++it, cend, a);
114  }
115 }
decltype(auto) constexpr cend(T &&obj)
ADL-aware version of std::cend.
Definition: StdUtils.h:93
Keys get_names(std::string const &key)
std::string const & name() const noexcept
std::vector< std::size_t > const & indices() const noexcept
intermediate_table::const_iterator const_iterator
std::vector< std::any > ps_sequence_t
Definition: coding.h:45
std::vector< std::string > const & tables() const noexcept
std::vector< std::string > tables_
std::vector< std::size_t > indices_
constexpr std::array< std::size_t, geo::vect::dimension< Vector >)> indices()
Returns a sequence of indices valid for a vector of the specified type.
bool find_an_any(std::vector< std::size_t >::const_iterator it, std::vector< std::size_t >::const_iterator const cend, std::any &a)
SequenceKey get_sequence_indices(std::string const &key)
SequenceKey(std::string const &name, std::vector< std::size_t > const &indices)
Keys(std::vector< std::string > const &keys, std::string const &last)
std::string const & last() const noexcept
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33