21#include <fmt/format.h>
33template<
typename KeyType,
typename Scalar,
bool unordered = true>
52 [[nodiscard]]
decltype(
auto)
begin()
const noexcept {
return _lookup.begin(); }
56 [[nodiscard]]
decltype(
auto)
cbegin()
const noexcept {
return _lookup.cbegin(); }
65 [[nodiscard]]
decltype(
auto)
end()
const noexcept {
return _lookup.end(); }
69 [[nodiscard]]
decltype(
auto)
cend()
const noexcept {
return _lookup.cend(); }
76 [[nodiscard]]
bool empty()
const
82 [[nodiscard]]
size_t size()
const
105 void addKey(
const KeyType& key,
const Scalar& value) {
addKeys(std::vector<std::pair<KeyType, Scalar>>{ { key, value } }); }
111 std::vector<std::pair<KeyType, Scalar>> keyValues;
112 keyValues.reserve(
keys.size());
113 for (
const KeyType& key :
keys)
115 keyValues.emplace_back(key, Scalar{});
123 void addKeys(std::span<const KeyType>
keys, std::span<const Scalar> values)
127 std::vector<std::pair<KeyType, Scalar>> keyValues;
128 keyValues.reserve(
keys.size());
129 for (
size_t i = 0; i <
keys.size(); i++)
131 keyValues.emplace_back(
keys[i], values[i]);
138 void addKeys(std::span<
const std::pair<KeyType, Scalar>> keyValues)
142 for ([[maybe_unused]]
const auto& keyValue : keyValues)
147 _data.emplace(keyValues.front().first, std::vector<Scalar>(keyValues.size()));
148 for (
size_t i = 0; i < keyValues.size(); i++)
150 _lookup[keyValues[i].first] = &
_data.at(keyValues.front().first).at(i);
151 _data.at(keyValues.front().first).at(i) = keyValues[i].second;
163 Scalar&
at(
const KeyType& key)
172 [[nodiscard]]
const Scalar&
at(
const KeyType& key)
const
181 std::vector<Scalar>&
at(std::span<const KeyType>
keys)
193 [[nodiscard]]
const std::vector<Scalar>&
at(std::span<const KeyType>
keys)
const
204 [[nodiscard]]
bool contains(
const KeyType& key)
const
216 return std::all_of(
keys.begin(),
keys.end(), [&](
const auto& key) { return _lookup.contains(key); });
221 [[nodiscard]]
size_t size_of(
const KeyType& key)
const
223 return _data.contains(key) ?
_data.at(key).size() : (
_lookup.contains(key) ? 1 : 0);
232 [[nodiscard]] std::vector<KeyType>
keys()
const
234 std::vector<KeyType>
keys;
236 for (
const auto& keyVal :
_lookup)
238 keys.push_back(keyVal.first);
248 std::conditional_t<unordered,
250 std::map<KeyType, std::vector<Scalar>>>
256#ifndef DOXYGEN_IGNORE
259template<
typename KeyType,
typename Scalar,
bool unordered>
260struct fmt::formatter<
NAV::KeyedMap<KeyType, Scalar, unordered>> : fmt::formatter<std::string>
269 auto length =
static_cast<size_t>(map.
size());
273 std::vector<std::string> rowKeysStr;
274 std::vector<size_t> rowKeysLength;
275 rowKeysStr.reserve(length);
276 rowKeysLength.reserve(length);
277 size_t rowKeysColSpace = 0;
278 for (
const auto& keyVal : map)
280 rowKeysStr.push_back(fmt::format(
"{}", keyVal.first));
281 auto rowKeyLength = rowKeysStr.back().length();
282 rowKeysColSpace = std::max(rowKeysColSpace, rowKeyLength);
283 rowKeysLength.push_back(rowKeyLength);
286 size_t colLength = 9UL;
288 result.reserve(length * (rowKeysColSpace + 2 + colLength));
291 for (
const auto& keyVal : map)
293 if (rowKeysColSpace > rowKeysLength.at(r))
295 result += std::string(rowKeysColSpace - rowKeysLength.at(r),
' ');
297 result += rowKeysStr.at(r);
299 std::string tmp = fmt::format(
" {:> {}.{}g}", *keyVal.second, colLength, colLength - 2);
300 if (tmp.length() > colLength)
302 tmp = fmt::format(
" {:> {}.{}g}", *keyVal.second, colLength, colLength - 6);
306 if (r != length - 1) { result +=
'\n'; }
311 return fmt::formatter<std::string>::format(result, ctx);
321template<
typename KeyType,
typename Scalar,
bool unordered>
324 return os << fmt::format(
"{}", obj);
#define INS_ASSERT_USER_ERROR(_EXP, _MSG)
Assert function with message.
std::ostream & operator<<(std::ostream &os, const NAV::KeyedMap< KeyType, Scalar, unordered > &obj)
Stream insertion operator overload.
ankerl::unordered_dense::map< Key, T > unordered_map
Unordered map type.
Similar to KeyedMatrix, but memory is allocated in a map and therefore never reallocated.
void addKeys(std::span< const KeyType > keys, std::span< const Scalar > values)
Adds a continuous vector for the keys to the data storage.
std::conditional_t< unordered, unordered_map< KeyType, std::vector< Scalar > >, std::map< KeyType, std::vector< Scalar > > > _data
Storage container.
decltype(auto) cbegin() const noexcept
Returns an iterator to the first element.
decltype(auto) cend() const noexcept
Returns an iterator to the element following the last element of.
std::vector< Scalar > & at(std::span< const KeyType > keys)
Returns a reference to the mapped value of the element with specified keys. If no such element exists...
decltype(auto) end()
Returns an iterator to the element following the last element of.
decltype(auto) end() const noexcept
Returns an iterator to the element following the last element of.
unordered_map< KeyType, Scalar * > _lookup
Lookup for individual keys.
const std::vector< Scalar > & at(std::span< const KeyType > keys) const
Returns a reference to the mapped value of the element with specified keys. If no such element exists...
bool contains(std::span< const KeyType > keys) const
Checks if there are elements with keys equivalent to keys in the container.
Scalar & at(const KeyType &key)
Returns a reference to the mapped value of the element with specified key. If no such element exists,...
void addKey(const KeyType &key, const Scalar &value)
Adds a single element for the key to the data storage.
const Scalar & at(const KeyType &key) const
Returns a reference to the mapped value of the element with specified key. If no such element exists,...
void addKey(const KeyType &key)
Adds a single element for the key to the data storage.
bool contains(const KeyType &key) const
Checks if there is an element with key equivalent to key in the container.
void addKeys(std::span< const std::pair< KeyType, Scalar > > keyValues)
Adds a continuous vector for the keys to the data storage.
std::vector< KeyType > keys() const
Collect all keys.
size_t size_of(const KeyType &key) const
Returns the size of parameters represented by the key.
size_t size() const
Returns the number of elements in the container.
decltype(auto) begin()
Returns an iterator to the first element.
void addKeys(std::span< const KeyType > keys)
Adds a continuous vector for the keys to the data storage.
bool empty() const
Checks if the container has no elements.
void clear()
Erases all elements from the container. After this call, size() returns zero.
decltype(auto) begin() const noexcept
Returns an iterator to the first element.