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.