LSST Applications g063fba187b+cac8b7c890,g0f08755f38+6aee506743,g1653933729+a8ce1bb630,g168dd56ebc+a8ce1bb630,g1a2382251a+b4475c5878,g1dcb35cd9c+8f9bc1652e,g20f6ffc8e0+6aee506743,g217e2c1bcf+73dee94bd0,g28da252d5a+1f19c529b9,g2bbee38e9b+3f2625acfc,g2bc492864f+3f2625acfc,g3156d2b45e+6e55a43351,g32e5bea42b+1bb94961c2,g347aa1857d+3f2625acfc,g35bb328faa+a8ce1bb630,g3a166c0a6a+3f2625acfc,g3e281a1b8c+c5dd892a6c,g3e8969e208+a8ce1bb630,g414038480c+5927e1bc1e,g41af890bb2+8a9e676b2a,g7af13505b9+809c143d88,g80478fca09+6ef8b1810f,g82479be7b0+f568feb641,g858d7b2824+6aee506743,g89c8672015+f4add4ffd5,g9125e01d80+a8ce1bb630,ga5288a1d22+2903d499ea,gb58c049af0+d64f4d3760,gc28159a63d+3f2625acfc,gcab2d0539d+b12535109e,gcf0d15dbbd+46a3f46ba9,gda6a2b7d83+46a3f46ba9,gdaeeff99f8+1711a396fd,ge79ae78c31+3f2625acfc,gef2f8181fd+0a71e47438,gf0baf85859+c1f95f4921,gfa517265be+6aee506743,gfa999e8aa5+17cd334064,w.2024.51
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)