LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
ParameterSetImplHelpers.h
Go to the documentation of this file.
1 #ifndef fhiclcpp_detail_ParameterSetImplHelpers_h
2 #define fhiclcpp_detail_ParameterSetImplHelpers_h
3 
4 #include "boost/algorithm/string.hpp"
5 #include "cetlib/container_algorithms.h"
6 #include "cetlib/split_by_regex.h"
7 #include "fhiclcpp/exception.h"
8 
9 #include <algorithm>
10 #include <string>
11 #include <vector>
12 
13 namespace fhicl {
14  namespace detail {
15 
16  //===============================================================
17  // get_names
18 
19  class Keys {
20  public:
21  Keys(std::vector<std::string> const& keys, std::string const& last)
22  : tables_{keys}, last_{last}
23  {}
24 
25  auto const&
26  tables() const
27  {
28  return tables_;
29  }
30  auto const&
31  last() const
32  {
33  return last_;
34  }
35 
36  private:
37  std::vector<std::string> tables_;
38  std::string last_;
39  };
40 
41  inline Keys
42  get_names(std::string const& key)
43  {
44  std::vector<std::string> keys;
45  boost::algorithm::split(keys, key, boost::algorithm::is_any_of("."));
46 
47  // Remove empty keys
48  keys.erase(std::remove(keys.begin(), keys.end(), ""), keys.end());
49 
50  if (keys.empty())
51  throw fhicl::exception(cant_find, "vacuous key");
52 
53  std::string const last = keys.back();
54  keys.pop_back();
55 
56  return Keys{keys, last};
57  }
58 
59  //===============================================================
60  // get_sequence_indices
61 
62  class SequenceKey {
63  public:
64  SequenceKey(std::string const& name,
65  std::vector<std::size_t> const& indices)
66  : name_{name}, indices_{indices}
67  {}
68 
69  auto const&
70  name() const
71  {
72  return name_;
73  }
74  auto const&
75  indices() const
76  {
77  return indices_;
78  }
79 
80  private:
81  std::string name_;
82  std::vector<std::size_t> indices_;
83  };
84 
85  inline SequenceKey
86  get_sequence_indices(std::string const& key)
87  {
88 
89  // Split "name[0][5][1]" according to delimiters "][", "[", and "]"
90  // to give {"name","0","5","1"};
91  auto tokens = cet::split_by_regex(key, R"((\]\[|\[|\]))");
92 
93  auto const name = tokens.front();
94  tokens.erase(tokens.begin());
95 
96  std::vector<std::size_t> indices;
97  cet::transform_all(
98  tokens, std::back_inserter(indices), [](std::string const& index) {
99  return std::stoul(index);
100  });
101 
102  return SequenceKey{name, indices};
103  }
104 
105  //===============================================================
106  // find_an_any
107 
109 
110  inline bool
111  find_an_any(cit_size_t it, cit_size_t const cend, boost::any& a)
112  {
113  if (it == cend) {
114  // If we got this far, that means the element must exist,
115  // otherwise the previous recursive 'find_parameter' call would
116  // have returned false.
117  return true;
118  }
119 
120  auto const seq = boost::any_cast<ps_sequence_t>(a);
121 
122  if (*it >= seq.size())
123  return false;
124 
125  a = seq[*it];
126 
127  return find_an_any(++it, cend, a);
128  }
129  }
130 }
131 
132 #endif /* fhiclcpp_detail_ParameterSetImplHelpers_h */
133 
134 // Local variables:
135 // mode: c++
136 // End:
auto const & last() const
Keys get_names(std::string const &key)
std::vector< std::string > tables_
intermediate_table::const_iterator const_iterator
parameter set interface
auto const & tables() const
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.
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::vector< std::size_t >::const_iterator cit_size_t
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
std::vector< boost::any > ps_sequence_t
Definition: coding.h:46
bool find_an_any(cit_size_t it, cit_size_t const cend, boost::any &a)