SatNOGS-COMMS  4.1.0
A COMMS subsystem for CubeSats
Loading...
Searching...
No Matches
hash_map.hpp
Go to the documentation of this file.
1/* MIT License
2
3Copyright (c) 2021 Karel Burda
4
5Permission is hereby granted, free of charge, to any person obtaining a copy
6of this software and associated documentation files (the "Software"), to deal
7in the Software without restriction, including without limitation the rights
8to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9copies of the Software, and to permit persons to whom the Software is
10furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice shall be included in all
13copies or substantial portions of the Software.
14
15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21SOFTWARE. */
22
23/*
24 * Modifications and Customizations
25 *
26 * Copyright (C) 2025, Libre Space Foundation <http://libre.space>
27 *
28 * This program is free software: you can redistribute it and/or modify
29 * it under the terms of the GNU General Public License as published by
30 * the Free Software Foundation, either version 3 of the License, or
31 * (at your option) any later version.
32 *
33 * This program is distributed in the hope that it will be useful,
34 * but WITHOUT ANY WARRANTY; without even the implied warranty of
35 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36 * GNU General Public License for more details.
37 *
38 * You should have received a copy of the GNU General Public License
39 * along with this program. If not, see <http://www.gnu.org/licenses/>.
40 *
41 * SPDX-License-Identifier: GNU General Public License v3.0 or later
42 */
43
44#pragma once
45
46#include <array>
47#include <cstddef>
48#include <iterator>
49#include <utility>
50
52{
53
65template <std::size_t N, typename K, typename V> class hash_map
66{
67public:
69 using key_type = K;
71 using value_type = V;
73 using size_type = decltype(N);
75 using data_type = std::array<std::pair<K, V>, N>;
77 using const_iterator = typename data_type::const_iterator;
78
83 template <typename... E>
84 explicit constexpr hash_map(E &&...elements) noexcept
85 : data{std::forward<E>(elements)...}
86 {
87 static_assert(N > 0, "N should be positive");
88 static_assert(N == sizeof...(elements),
89 "Elements size doesn't match expected size of a hash-map");
90 }
91
95 [[nodiscard]] constexpr const_iterator
96 find(const K &key) const noexcept
97 {
98 return search<0, N>(key);
99 }
100
108 [[nodiscard]] constexpr std::pair<bool, const V &>
109 at(const K &key) const noexcept
110 {
111 const auto it = find(key);
112
113 if (it != cend()) {
114 return {true, it->second};
115 }
116
117 return {false, {}};
118 }
119
125 // NOLINTNEXTLINE(fuchsia-overloaded-operator)
126 [[nodiscard]] constexpr const V &
127 operator[](const K &key) const noexcept
128 {
129 return find(key)->second;
130 }
131
135 [[nodiscard]] constexpr bool
136 contains(const K &key) const noexcept
137 {
138 return search<0, N>(key) != cend();
139 }
140
144 [[nodiscard]] constexpr size_type
145 size() const noexcept
146 {
147 return data.size();
148 }
149
154 [[nodiscard]] constexpr const_iterator
155 begin() const noexcept
156 {
157 return cbegin();
158 }
159
164 [[nodiscard]] constexpr const_iterator
165 cbegin() const noexcept
166 {
167 return std::cbegin(data);
168 }
169
174 [[nodiscard]] constexpr const_iterator
175 end() const noexcept
176 {
177 return cend();
178 }
179
184 [[nodiscard]] constexpr const_iterator
185 cend() const noexcept
186 {
187 return std::cend(data);
188 }
189
194 [[nodiscard]] constexpr bool
195 empty() const noexcept
196 {
197 return false;
198 }
199
202 [[nodiscard]] constexpr std::array<K, N>
203 keys() const noexcept
204 {
205 return keys_impl(std::make_index_sequence<N>{});
206 }
207
208protected:
210 using index_type = size_type;
211
214 template <index_type L, index_type R>
215 [[nodiscard]] constexpr const_iterator
216 search(const K &key) const noexcept
217 {
218 if constexpr (L < R) {
219 if (equal(data[L].first, key)) {
220 return std::next(cbegin(), L);
221 }
222
223 return search<L + 1, R>(key);
224 }
225
226 return cend();
227 }
228
230 template <typename T = K>
231 [[nodiscard]] constexpr bool
232 equal(const T &lhs, const T &rhs) const noexcept
233 {
234 return lhs == rhs;
235 }
236
239 [[nodiscard]] constexpr bool
240 equal(const char *lhs, const char *rhs) const noexcept
241 {
242 // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
243 return *lhs == *rhs && (*lhs == '\0' || equal(lhs + 1, rhs + 1));
244 }
245
246 template <const auto... KeyIdx>
247 [[nodiscard]] constexpr std::array<K, N>
248 keys_impl(std::index_sequence<KeyIdx...>) const
249 {
250 return {data[KeyIdx].first...};
251 }
252
253private:
254 data_type data;
255};
256
257} // namespace satnogs::comms::utils
constexpr hash_map(E &&...elements) noexcept
The only construction that might be used, all keys and values must be provided in the constructor.
Definition hash_map.hpp:84
constexpr const_iterator end() const noexcept
Gives constant iterator to an end, needed for the C++11 for-each cycle or the std::for_each.
Definition hash_map.hpp:175
constexpr std::array< K, N > keys_impl(std::index_sequence< KeyIdx... >) const
Definition hash_map.hpp:248
constexpr size_type size() const noexcept
Retrieves size of a hash-map, might also be called indirectly using the std::size(....
Definition hash_map.hpp:145
constexpr const_iterator cend() const noexcept
Gives constant iterator to a beginning, might be also called using std::cend(...).
Definition hash_map.hpp:185
constexpr std::pair< bool, const V & > at(const K &key) const noexcept
Searches for a given key, aimed to return associated value with it.
Definition hash_map.hpp:109
std::array< std::pair< K, V >, N > data_type
underlying structure used for the actual implementation
Definition hash_map.hpp:75
constexpr const_iterator begin() const noexcept
Gives constant iterator to a beginning, needed for the C++11 for-each cycle or the std::for_each.
Definition hash_map.hpp:155
constexpr const_iterator cbegin() const noexcept
Gives constant iterator to a beginning, might be also called using std::cbegin(......
Definition hash_map.hpp:165
constexpr bool empty() const noexcept
Hash-map cannot be empty; this might also be called using std::empty(...).
Definition hash_map.hpp:195
constexpr const_iterator find(const K &key) const noexcept
Searches map for a given key and returns iterator.
Definition hash_map.hpp:96
constexpr std::array< K, N > keys() const noexcept
Returns all keys in the hash-map.
Definition hash_map.hpp:203
typename data_type::const_iterator const_iterator
Definition hash_map.hpp:77
constexpr const V & operator[](const K &key) const noexcept
Retrieves reference to constant to a value. Doesn't perform any bounds checking, behaviour is undefin...
Definition hash_map.hpp:127
constexpr bool contains(const K &key) const noexcept
Checks if element with given key exists.
Definition hash_map.hpp:136