Skip to main content
Code Review

Return to Answer

Notice removed Insufficient justification by Sᴀᴍ Onᴇᴌᴀ
added Explanation
Source Link
dameo
  • 193
  • 7

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.

Notice added Insufficient justification by Mast
added 2 characters in body
Source Link
toolic
  • 14.4k
  • 5
  • 29
  • 201

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;
}
Source Link
dameo
  • 193
  • 7

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;
}
```
lang-cpp

AltStyle によって変換されたページ (->オリジナル) /