LSST Applications 26.0.0,g0265f82a02+6660c170cc,g07994bdeae+30b05a742e,g0a0026dc87+17526d298f,g0a60f58ba1+17526d298f,g0e4bf8285c+96dd2c2ea9,g0ecae5effc+c266a536c8,g1e7d6db67d+6f7cb1f4bb,g26482f50c6+6346c0633c,g2bbee38e9b+6660c170cc,g2cc88a2952+0a4e78cd49,g3273194fdb+f6908454ef,g337abbeb29+6660c170cc,g337c41fc51+9a8f8f0815,g37c6e7c3d5+7bbafe9d37,g44018dc512+6660c170cc,g4a941329ef+4f7594a38e,g4c90b7bd52+5145c320d2,g58be5f913a+bea990ba40,g635b316a6c+8d6b3a3e56,g67924a670a+bfead8c487,g6ae5381d9b+81bc2a20b4,g93c4d6e787+26b17396bd,g98cecbdb62+ed2cb6d659,g98ffbb4407+81bc2a20b4,g9ddcbc5298+7f7571301f,ga1e77700b3+99e9273977,gae46bcf261+6660c170cc,gb2715bf1a1+17526d298f,gc86a011abf+17526d298f,gcf0d15dbbd+96dd2c2ea9,gdaeeff99f8+0d8dbea60f,gdb4ec4c597+6660c170cc,ge23793e450+96dd2c2ea9,gf041782ebf+171108ac67
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
decltype(_typeToConstRef(std::declval< StorableType >())) ConstValueReference
A type-agnostic reference to the value stored inside the map.
Definition GenericMap.h:369
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:360
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)
T cref(T... args)
T size(T... args)
T str(T... args)
T swap(T... args)
T throw_with_nested(T... args)