Explanation
It seems impossible to write using a constructor and an initialization list even in C++23, so I searched for a similar method and ended up creating my own iterator. When I created my own iterator, the code became longer than I expected, but I was able to cleanly initialize std::map with a single constructor.
Explanation
It seems impossible to write using a constructor and an initialization list even in C++23, so I searched for a similar method and ended up creating my own iterator. When I created my own iterator, the code became longer than I expected, but I was able to cleanly initialize std::map with a single constructor.
How about something like this using iterator?
#include <iostream>
#include <map>
#include <sstream>
#include <iomanip>
#include <iterator>
#include <utility>
#include <type_traits>
#include "magic_enum.hpp" // https://github.com/Neargye/magic_enum/releases/download/v0.8.1/magic_enum.hpp
enum TCPSTATUS {
UNKNOWN, ESTABLISHED, SYN_SENT, SYN_RECV, FIN_WAIT1, FIN_WAIT2, TIME_WAIT, CLOSE, CLOSE_WAIT, LAST_ACK, LISTEN, CLOSING,
};
using tcpstatus_values_iterator = decltype(magic_enum::enum_values<TCPSTATUS>().begin());
class pair_generator_iterator {
tcpstatus_values_iterator _iter;
static std::string generate_key(TCPSTATUS i) {
std::stringstream ss;
ss << std::hex << std::uppercase << std::setw(2) << std::setfill('0') << magic_enum::enum_integer(i);
return ss.str();
}
public:
using original_value_type = TCPSTATUS;
using key_type = decltype(generate_key(UNKNOWN));
using iterator_category = std::input_iterator_tag;
using difference_type = int;
using value_type = std::pair<key_type, original_value_type>;
using pointer = value_type*;
using reference = value_type&;
pair_generator_iterator(tcpstatus_values_iterator iter): _iter{iter} {}
value_type operator*() const {
original_value_type v = *_iter;
return make_pair(generate_key(v), v);
}
pair_generator_iterator& operator++() {
_iter++;
return *this;
}
friend bool operator== (const pair_generator_iterator& a, const pair_generator_iterator& b) { return a._iter == b._iter; }
friend bool operator!= (const pair_generator_iterator& a, const pair_generator_iterator& b) { return !(a == b); }
};
std::map<std::string, TCPSTATUS> table{
pair_generator_iterator(magic_enum::enum_values<TCPSTATUS>().begin()),
pair_generator_iterator(magic_enum::enum_values<TCPSTATUS>().end())
};
int main(int argc, char* argv[]) {
for (const auto& p: table) {
std::cout << p.first << "->" << magic_enum::enum_name(p.second) << std::endl;
}
return 0;
}
```
How about something like this using iterator?
#include <iostream>
#include <map>
#include <sstream>
#include <iomanip>
#include <iterator>
#include <utility>
#include <type_traits>
#include "magic_enum.hpp" // https://github.com/Neargye/magic_enum/releases/download/v0.8.1/magic_enum.hpp
enum TCPSTATUS {
UNKNOWN, ESTABLISHED, SYN_SENT, SYN_RECV, FIN_WAIT1, FIN_WAIT2, TIME_WAIT, CLOSE, CLOSE_WAIT, LAST_ACK, LISTEN, CLOSING,
};
using tcpstatus_values_iterator = decltype(magic_enum::enum_values<TCPSTATUS>().begin());
class pair_generator_iterator {
tcpstatus_values_iterator _iter;
static std::string generate_key(TCPSTATUS i) {
std::stringstream ss;
ss << std::hex << std::uppercase << std::setw(2) << std::setfill('0') << magic_enum::enum_integer(i);
return ss.str();
}
public:
using original_value_type = TCPSTATUS;
using key_type = decltype(generate_key(UNKNOWN));
using iterator_category = std::input_iterator_tag;
using difference_type = int;
using value_type = std::pair<key_type, original_value_type>;
using pointer = value_type*;
using reference = value_type&;
pair_generator_iterator(tcpstatus_values_iterator iter): _iter{iter} {}
value_type operator*() const {
original_value_type v = *_iter;
return make_pair(generate_key(v), v);
}
pair_generator_iterator& operator++() {
_iter++;
return *this;
}
friend bool operator== (const pair_generator_iterator& a, const pair_generator_iterator& b) { return a._iter == b._iter; }
friend bool operator!= (const pair_generator_iterator& a, const pair_generator_iterator& b) { return !(a == b); }
};
std::map<std::string, TCPSTATUS> table{
pair_generator_iterator(magic_enum::enum_values<TCPSTATUS>().begin()),
pair_generator_iterator(magic_enum::enum_values<TCPSTATUS>().end())
};
int main(int argc, char* argv[]) {
for (const auto& p: table) {
std::cout << p.first << "->" << magic_enum::enum_name(p.second) << std::endl;
}
return 0;
}
```
How about something like this using iterator?
#include <iostream>
#include <map>
#include <sstream>
#include <iomanip>
#include <iterator>
#include <utility>
#include <type_traits>
#include "magic_enum.hpp" // https://github.com/Neargye/magic_enum/releases/download/v0.8.1/magic_enum.hpp
enum TCPSTATUS {
UNKNOWN, ESTABLISHED, SYN_SENT, SYN_RECV, FIN_WAIT1, FIN_WAIT2, TIME_WAIT, CLOSE, CLOSE_WAIT, LAST_ACK, LISTEN, CLOSING,
};
using tcpstatus_values_iterator = decltype(magic_enum::enum_values<TCPSTATUS>().begin());
class pair_generator_iterator {
tcpstatus_values_iterator _iter;
static std::string generate_key(TCPSTATUS i) {
std::stringstream ss;
ss << std::hex << std::uppercase << std::setw(2) << std::setfill('0') << magic_enum::enum_integer(i);
return ss.str();
}
public:
using original_value_type = TCPSTATUS;
using key_type = decltype(generate_key(UNKNOWN));
using iterator_category = std::input_iterator_tag;
using difference_type = int;
using value_type = std::pair<key_type, original_value_type>;
using pointer = value_type*;
using reference = value_type&;
pair_generator_iterator(tcpstatus_values_iterator iter): _iter{iter} {}
value_type operator*() const {
original_value_type v = *_iter;
return make_pair(generate_key(v), v);
}
pair_generator_iterator& operator++() {
_iter++;
return *this;
}
friend bool operator== (const pair_generator_iterator& a, const pair_generator_iterator& b) { return a._iter == b._iter; }
friend bool operator!= (const pair_generator_iterator& a, const pair_generator_iterator& b) { return !(a == b); }
};
std::map<std::string, TCPSTATUS> table{
pair_generator_iterator(magic_enum::enum_values<TCPSTATUS>().begin()),
pair_generator_iterator(magic_enum::enum_values<TCPSTATUS>().end())
};
int main(int argc, char* argv[]) {
for (const auto& p: table) {
std::cout << p.first << "->" << magic_enum::enum_name(p.second) << std::endl;
}
return 0;
}
How about something like this using iterator?
#include <iostream>
#include <map>
#include <sstream>
#include <iomanip>
#include <iterator>
#include <utility>
#include <type_traits>
#include "magic_enum.hpp" // https://github.com/Neargye/magic_enum/releases/download/v0.8.1/magic_enum.hpp
enum TCPSTATUS {
UNKNOWN, ESTABLISHED, SYN_SENT, SYN_RECV, FIN_WAIT1, FIN_WAIT2, TIME_WAIT, CLOSE, CLOSE_WAIT, LAST_ACK, LISTEN, CLOSING,
};
using tcpstatus_values_iterator = decltype(magic_enum::enum_values<TCPSTATUS>().begin());
class pair_generator_iterator {
tcpstatus_values_iterator _iter;
static std::string generate_key(TCPSTATUS i) {
std::stringstream ss;
ss << std::hex << std::uppercase << std::setw(2) << std::setfill('0') << magic_enum::enum_integer(i);
return ss.str();
}
public:
using original_value_type = TCPSTATUS;
using key_type = decltype(generate_key(UNKNOWN));
using iterator_category = std::input_iterator_tag;
using difference_type = int;
using value_type = std::pair<key_type, original_value_type>;
using pointer = value_type*;
using reference = value_type&;
pair_generator_iterator(tcpstatus_values_iterator iter): _iter{iter} {}
value_type operator*() const {
original_value_type v = *_iter;
return make_pair(generate_key(v), v);
}
pair_generator_iterator& operator++() {
_iter++;
return *this;
}
friend bool operator== (const pair_generator_iterator& a, const pair_generator_iterator& b) { return a._iter == b._iter; }
friend bool operator!= (const pair_generator_iterator& a, const pair_generator_iterator& b) { return !(a == b); }
};
std::map<std::string, TCPSTATUS> table{
pair_generator_iterator(magic_enum::enum_values<TCPSTATUS>().begin()),
pair_generator_iterator(magic_enum::enum_values<TCPSTATUS>().end())
};
int main(int argc, char* argv[]) {
for (const auto& p: table) {
std::cout << p.first << "->" << magic_enum::enum_name(p.second) << std::endl;
}
return 0;
}
```