registry_via_id.h
Go to the documentation of this file.
1 #ifndef cetlib_registry_via_id_h
2 #define cetlib_registry_via_id_h
3 
4 // ======================================================================
5 //
6 // registry_via_id<K,V>: A singleton std::map<K,V> requiring that V::id()
7 // exists and yields values of type K
8 //
9 // ======================================================================
10 
11 #include "cetlib_except/exception.h"
12 
13 #include <iterator>
14 #include <map>
15 #include <stdexcept>
16 #include <type_traits>
17 #include <utility>
18 
19 namespace cet {
20  template <class K, class V>
22 
23  namespace detail {
24  template <class K, class V, K (V::*)() const = &V::id>
25  struct must_have_id {
26  typedef K type;
27  };
28  }
29 }
30 
31 // ======================================================================
32 
33 template <class K, class V>
35  // non-instantiable (and non-copyable, just in case):
36  registry_via_id() = delete;
37  registry_via_id(registry_via_id const&) = delete;
38  void operator=(registry_via_id const&) = delete;
39 
40 public:
41  typedef std::map<K const, V> collection_type;
42  typedef typename collection_type::key_type key_type;
43  typedef typename collection_type::mapped_type mapped_type;
44  typedef typename collection_type::value_type value_type;
46  typedef typename collection_type::const_iterator const_iterator;
47 
48  // observers:
49  static bool
51  {
52  return the_registry_().empty();
53  }
54  static size_type
55  size()
56  {
57  return the_registry_().size();
58  }
59 
60  // iterators:
61  static const_iterator
63  {
64  return the_registry_().begin();
65  }
66  static const_iterator
67  end()
68  {
69  return the_registry_().end();
70  }
71  static const_iterator
73  {
74  return the_registry_().cbegin();
75  }
76  static const_iterator
77  cend()
78  {
79  return the_registry_().cend();
80  }
81 
82  // mutators:
83  // A single V;
84  static typename detail::must_have_id<K, V>::type put(V const& value);
85  // A range of iterator to V.
86  template <class FwdIt>
87  static std::enable_if_t<
88  std::is_same<typename std::iterator_traits<FwdIt>::value_type,
89  mapped_type>::value,
90  void>
91  put(FwdIt begin, FwdIt end);
92  // A range of iterator to std::pair<K, V>. For each pair, first ==
93  // second.id() is a prerequisite.
94  template <class FwdIt>
95  static std::enable_if_t<
96  std::is_same<typename std::iterator_traits<FwdIt>::value_type,
97  value_type>::value,
98  void>
99  put(FwdIt begin, FwdIt end);
100  // A collection_type. For each value_type, first == second.id() is a
101  // prerequisite.
102  static void put(collection_type const& c);
103 
104  // accessors:
105  static collection_type const&
106  get() noexcept
107  {
108  return the_registry_();
109  }
110  static V const& get(K const& key);
111  static bool get(K const& key, V& value) noexcept;
112 
113 private:
114  // encapsulated singleton:
115  static collection_type&
117  {
118  static collection_type the_registry;
119  return the_registry;
120  }
121 
122 }; // registry_via_id<>
123 
124 // ----------------------------------------------------------------------
125 // put() overloads:
126 
127 template <class K, class V>
130 {
131  K id = value.id();
132  the_registry_().emplace(id, value);
133  return id;
134 }
135 
136 template <class K, class V>
137 template <class FwdIt>
138 inline auto
139 cet::registry_via_id<K, V>::put(FwdIt b, FwdIt e) -> std::enable_if_t<
140  std::is_same<typename std::iterator_traits<FwdIt>::value_type,
142  void>
143 {
144  for (; b != e; ++b)
145  (void)put(*b);
146 }
147 
148 template <class K, class V>
149 template <class FwdIt>
150 inline auto
151 cet::registry_via_id<K, V>::put(FwdIt b, FwdIt e) -> std::enable_if_t<
152  std::is_same<typename std::iterator_traits<FwdIt>::value_type,
154  void>
155 {
156  the_registry_().insert(b, e);
157 }
158 
159 template <class K, class V>
160 inline void
162 {
163  put(c.cbegin(), c.cend());
164 }
165 
166 // ----------------------------------------------------------------------
167 // get() overloads:
168 
169 template <class K, class V>
170 V const&
172 {
173  const_iterator it = the_registry_().find(key);
174  if (it == the_registry_().end())
175  throw cet::exception("cet::registry_via_id")
176  << "Key \"" << key << "\" not found in registry";
177  return it->second;
178 }
179 
180 template <class K, class V>
181 bool
183 {
184  bool result;
185  const_iterator it = the_registry_().find(key);
186  if (it == the_registry_().end()) {
187  result = false;
188  } else {
189  value = it->second;
190  result = true;
191  }
192  return result;
193 }
194 
195 #endif /* cetlib_registry_via_id_h */
196 
197 // Local Variables:
198 // mode: c++
199 // End:
::xsd::cxx::tree::id< char, ncname > id
Definition: Database.h:165
collection_type::const_iterator const_iterator
set< int >::iterator it
static const_iterator begin()
::xsd::cxx::tree::exception< char > exception
Definition: Database.h:225
static const_iterator end()
Double_t K
collection_type::mapped_type mapped_type
static collection_type & the_registry_()
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic >::Index size_type
Definition: typedefs.hpp:11
static const_iterator cend()
const XML_Char int const XML_Char * value
Definition: expat.h:331
collection_type::size_type size_type
collection_type::key_type key_type
static collection_type const & get() noexcept
static size_type size()
const hit & b
Definition: hits.cxx:21
static detail::must_have_id< K, V >::type put(V const &value)
static const_iterator cbegin()
Float_t e
Definition: plot.C:35
collection_type::value_type value_type
std::map< K const, V > collection_type