LSST Applications g180d380827+0f66a164bb,g2079a07aa2+86d27d4dc4,g2305ad1205+7d304bc7a0,g29320951ab+500695df56,g2bbee38e9b+0e5473021a,g337abbeb29+0e5473021a,g33d1c0ed96+0e5473021a,g3a166c0a6a+0e5473021a,g3ddfee87b4+e42ea45bea,g48712c4677+36a86eeaa5,g487adcacf7+2dd8f347ac,g50ff169b8f+96c6868917,g52b1c1532d+585e252eca,g591dd9f2cf+c70619cc9d,g5a732f18d5+53520f316c,g5ea96fc03c+341ea1ce94,g64a986408d+f7cd9c7162,g858d7b2824+f7cd9c7162,g8a8a8dda67+585e252eca,g99cad8db69+469ab8c039,g9ddcbc5298+9a081db1e4,ga1e77700b3+15fc3df1f7,gb0e22166c9+60f28cb32d,gba4ed39666+c2a2e4ac27,gbb8dafda3b+c92fc63c7e,gbd866b1f37+f7cd9c7162,gc120e1dc64+02c66aa596,gc28159a63d+0e5473021a,gc3e9b769f7+b0068a2d9f,gcf0d15dbbd+e42ea45bea,gdaeeff99f8+f9a426f77a,ge6526c86ff+84383d05b3,ge79ae78c31+0e5473021a,gee10cc3b42+585e252eca,gff1a9f87cc+f7cd9c7162,w.2024.17
LSST Data Management Base Package
Loading...
Searching...
No Matches
SimpleGenericMap.h
Go to the documentation of this file.
1// -*- LSST-C++ -*-
2/*
3 * This file is part of afw.
4 *
5 * Developed for the LSST Data Management System.
6 * This product includes software developed by the LSST Project
7 * (https://www.lsst.org).
8 * See the COPYRIGHT file at the top-level directory of this distribution
9 * for details of code ownership.
10 *
11 * This program is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation, either version 3 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program. If not, see <https://www.gnu.org/licenses/>.
23 */
24
25#ifndef LSST_AFW_TYPEHANDLING_SIMPLEGENERICMAP_H
26#define LSST_AFW_TYPEHANDLING_SIMPLEGENERICMAP_H
27
28#include <exception>
29#include <sstream>
30#include <unordered_map>
31#include <utility>
32#include <variant>
33
35
36namespace lsst {
37namespace afw {
38namespace typehandling {
39
48template <typename K>
49class SimpleGenericMap final : public MutableGenericMap<K> {
50protected:
51 using typename GenericMap<K>::StorableType;
53
54public:
55 SimpleGenericMap() = default;
56 SimpleGenericMap(SimpleGenericMap const& other) = default;
57 SimpleGenericMap(SimpleGenericMap&&) noexcept = default;
65 SimpleGenericMap(GenericMap<K> const& other) : _storage(_convertStorage(other)), _keyView(other.keys()) {}
66 virtual ~SimpleGenericMap() noexcept = default;
67
68 SimpleGenericMap& operator=(SimpleGenericMap const& other) {
69 std::vector<K> newKeys = other._keyView;
70 _storage = other._storage;
71 // strong exception safety because no exceptions can occur past this point
72 using std::swap;
73 swap(_keyView, newKeys);
74 return *this;
75 }
77 SimpleGenericMap& operator=(GenericMap<K> const& other) {
78 std::vector<K> newKeys = other.keys();
79 // strong exception safety: unordered_map is nothrow move-assignable and
80 // vector is nothrow swappable, so no exceptions can occur after _convertStorage returns
81 _storage = _convertStorage(other);
82 using std::swap;
83 swap(_keyView, newKeys);
84 return *this;
85 }
86
87 typename GenericMap<K>::size_type size() const noexcept override { return _storage.size(); }
88
89 bool empty() const noexcept override { return _storage.empty(); }
90
91 typename GenericMap<K>::size_type max_size() const noexcept override {
92 return std::min(_storage.max_size(), _keyView.max_size());
93 }
94
95 bool contains(K const& key) const override { return _storage.count(key) > 0; }
96
97 std::vector<K> const& keys() const noexcept override { return _keyView; }
98
99 void clear() noexcept override {
100 _storage.clear();
101 _keyView.clear();
102 }
103
104protected:
105 ConstValueReference unsafeLookup(K key) const override {
106 try {
107 return std::visit(
108 [](auto const & v) { return ConstValueReference(std::cref(v)); },
109 _storage.at(key)
110 );
111 } catch (std::out_of_range& e) {
112 std::stringstream message;
113 message << "Key not found: " << key;
115 }
116 }
117
118 bool unsafeInsert(K key, StorableType&& value) override {
119 std::vector<K> newKeys = _keyView;
120 newKeys.emplace_back(key);
121 bool inserted = _storage.emplace(key, std::move(value)).second;
122 // strong exception safety because no exceptions can occur past this point
123 if (inserted) {
124 // _storage did not previously include key, so the key appended to newKeys is unique
125 using std::swap;
126 swap(_keyView, newKeys);
127 }
128 return inserted;
129 }
130
131 bool unsafeErase(K key) override {
132 std::vector<K> newKeys = _keyView;
133 for (auto it = newKeys.cbegin(); it != newKeys.cend();) {
134 if (*it == key) {
135 it = newKeys.erase(it);
136 } else {
137 ++it;
138 }
139 }
140 // strong exception safety because no exceptions can occur past this point
141 bool erased = _storage.erase(key) > 0;
142 if (erased) {
143 using std::swap;
144 swap(_keyView, newKeys);
145 }
146 return erased;
147 }
148
149private:
150 // StorableType is a value, so we might as well use it in the implementation
152 std::vector<K> _keyView;
153 // Class invariant: the elements of _keyView are unique
154 // Class invariant: the elements of _keyView and the keys of _storage are the same
155 // Class invariant: the elements of _keyView are arranged in insertion order, oldest to newest
156
165 static std::unordered_map<K, StorableType> _convertStorage(GenericMap<K> const& map) {
167 map.apply([&newStorage](K const& key, auto const& value) { newStorage.emplace(key, value); });
168 return newStorage;
169 }
170};
171
172} // namespace typehandling
173} // namespace afw
174} // namespace lsst
175
176#endif
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition Exception.h:48
T at(T... args)
T cbegin(T... args)
Interface for a heterogeneous map.
Definition GenericMap.h:79
std::variant< bool, int, long, long long, float, double, std::string, PolymorphicValue, std::shared_ptr< Storable const > > StorableType
The types that can be stored in a map.
Definition GenericMap.h:359
decltype(_typeToConstRef(std::declval< StorableType >())) ConstValueReference
A type-agnostic reference to the value stored inside the map.
Definition GenericMap.h:369
auto apply(Visitor &&visitor) const
Apply an operation to each key-value pair in the map.
Definition GenericMap.h:309
Interface for a GenericMap that allows element addition and removal.
Definition GenericMap.h:597
A GenericMap that allows insertion and deletion of arbitrary values.
virtual ~SimpleGenericMap() noexcept=default
void clear() noexcept override
Remove all of the mappings from this map.
std::vector< K > const & keys() const noexcept override
Return the set of all keys, without type information.
GenericMap< K >::size_type size() const noexcept override
Return the number of key-value pairs in the map.
SimpleGenericMap(SimpleGenericMap const &other)=default
bool unsafeErase(K key) override
Remove the mapping for a key from this map, if it exists.
bool empty() const noexcept override
Return true if this map contains no key-value pairs.
SimpleGenericMap & operator=(SimpleGenericMap &&) noexcept=default
bool contains(K const &key) const override
Return true if this map contains a mapping whose key has the specified label.
ConstValueReference unsafeLookup(K key) const override
Return a reference to the mapped value of the element with key equal to key.
GenericMap< K >::size_type max_size() const noexcept override
Return the maximum number of elements the container is able to hold due to system or library implemen...
bool unsafeInsert(K key, StorableType &&value) override
Create a new mapping with key equal to key and value equal to value.
SimpleGenericMap(SimpleGenericMap &&) noexcept=default
Reports attempts to access elements outside a valid range of indices.
Definition Runtime.h:89
T clear(T... args)
T count(T... args)
T emplace_back(T... args)
T emplace(T... args)
T empty(T... args)
T cend(T... args)
T erase(T... args)
T max_size(T... args)
T min(T... args)
T move(T... args)
void swap(PolymorphicValue &lhs, PolymorphicValue &rhs) noexcept
Swap specialization for PolymorphicValue.
T cref(T... args)
T size(T... args)
T str(T... args)
T swap(T... args)
T throw_with_nested(T... args)