ESPHome 2026.2.3
Loading...
Searching...
No Matches
mapping.h
Go to the documentation of this file.
1#pragma once
2
4#include "esphome/core/log.h"
5#include <cinttypes>
6#include <map>
7#include <string>
8
9namespace esphome::mapping {
10
11using alloc_string_t = std::basic_string<char, std::char_traits<char>, RAMAllocator<char>>;
12
22static const char *const TAG = "mapping";
23
24template<typename K, typename V> class Mapping {
25 public:
26 // Constructor
27 Mapping() = default;
28
29 using key_t = const std::conditional_t<std::is_same_v<K, std::string>,
30 alloc_string_t, // if K is std::string, custom string type
31 K>;
32 using value_t = std::conditional_t<std::is_same_v<V, std::string>,
33 alloc_string_t, // if V is std::string, custom string type
34 V>;
35
36 void set(const K &key, const V &value) { this->map_[key_t{key}] = value; }
37
38 V get(const K &key) const {
39 auto it = this->map_.find(key_t{key});
40 if (it != this->map_.end()) {
41 return V{it->second};
42 }
43 if constexpr (std::is_pointer_v<K>) {
44 esph_log_e(TAG, "Key '%p' not found in mapping", key);
45 } else if constexpr (std::is_same_v<K, std::string>) {
46 esph_log_e(TAG, "Key '%s' not found in mapping", key.c_str());
47 } else if constexpr (std::is_integral_v<K>) {
48 char buf[24]; // enough for 64-bit integer
49 if constexpr (std::is_unsigned_v<K>) {
50 buf_append_printf(buf, sizeof(buf), 0, "%" PRIu64, static_cast<uint64_t>(key));
51 } else {
52 buf_append_printf(buf, sizeof(buf), 0, "%" PRId64, static_cast<int64_t>(key));
53 }
54 esph_log_e(TAG, "Key '%s' not found in mapping", buf);
55 } else {
56 // All supported key types are handled above - this should never be reached
57 static_assert(sizeof(K) == 0, "Unsupported key type for Mapping error logging");
58 }
59 return {};
60 }
61
62 // index map overload
63 V operator[](K key) { return this->get(key); }
64
65 // convenience function for strings to get a C-style string
66 template<typename T = V, std::enable_if_t<std::is_same_v<T, std::string>, int> = 0>
67 const char *operator[](K key) const {
68 auto it = this->map_.find(key_t{key});
69 if (it != this->map_.end()) {
70 return it->second.c_str(); // safe since value remains in map
71 }
72 return "";
73 }
74
75 protected:
76 std::map<key_t, value_t, std::less<key_t>, RAMAllocator<std::pair<key_t, value_t>>> map_;
77};
78
79} // namespace esphome::mapping
An STL allocator that uses SPI or internal RAM.
Definition helpers.h:1647
const char * operator[](K key) const
Definition mapping.h:67
void set(const K &key, const V &value)
Definition mapping.h:36
std::conditional_t< std::is_same_v< V, std::string >, alloc_string_t, V > value_t
Definition mapping.h:32
const std::conditional_t< std::is_same_v< K, std::string >, alloc_string_t, K > key_t
Definition mapping.h:29
V get(const K &key) const
Definition mapping.h:38
std::map< key_t, value_t, std::less< key_t >, RAMAllocator< std::pair< key_t, value_t > > > map_
Definition mapping.h:76
std::basic_string< char, std::char_traits< char >, RAMAllocator< char > > alloc_string_t
Definition mapping.h:11