1

I'm trying to store a std::map<enum, int> in a boost::beast::multi_buffer. So far I've been using boost::asio::buffer_copy and boost::asio::buffer to store vectors and PODs. However, I couldn't find a way to store a STL map.

I've tried this:

auto t_map = std::map<CODES, int>(); // CODES is an enum type

auto t_map_size = t_map.size() * sizeof(std::pair<CODES, int>);
auto tmp_buffer = boost::asio::buffer(t_map, t_map_size); // this is not supported

auto size = boost::asio::buffer_copy(t_map_size , tmp_buffer);

boost::beast::multi_buffer buffer;
buffer.commit(size);
  1. Is there any way to store a std::map<enum, int> in a ConstBufferSequence? (because the boost::asio::buffer_copy needs one)
  2. If not, is there any workaround to store a std::map<enum, int> in a boost::beast::multi_buffer?

Thanks!

Shmwel
  • 1,697
  • 5
  • 26
  • 43
  • You can never "store" anything in a Asio buffer (or sequence) because buffers only _reference_ existing data. Any buffer refers to contiguous region of POD data, and a buffer sequence combines several of those (to support "gather" buffers that aren't necessarily contiguous in memory) – sehe Feb 15 '19 at 15:34

1 Answers1

2

You can convert your map into vector of POD, as POD choose type which can store enum + int, for example int64_t:

So create vector, scan your map creating items of vector using some bitwise operations and data is ready:

auto t_map = std::map<CODES, int>(); // CODES is an enum type

std::vector<int64_t> vec;
for (auto&& elemMap : t_map)
{
    int64_t val = elemMap.first;   // store key
    val <<= 32; // shift key
    val |= elemMap.second; // store value

    vec.push_back (val);
}

auto tmp_buffer = boost::asio::buffer(vec); // this is supported

Unpack vector into map should be easy.

rafix07
  • 20,001
  • 3
  • 20
  • 33
  • Cool. So basically, this way is pretty much the best option to send custom types as well? – Shmwel Feb 15 '19 at 10:22
  • 1
    @Shmwel Input of `asio::buffer` is limited, it takes vector of POD, string, array of POD, or raw pointer + size, so some serialization method is needed to customize data before further processing. My answer showed one of possible way to do it. – rafix07 Feb 15 '19 at 10:25
  • I would stay away from low-level hacks to "pack" the value types. As it is, they're POD enough! You can actually be as concise as this: **[direct contiguous map copy](http://coliru.stacked-crooked.com/a/2464cb0087bf9fe2)**. If you look at the resulting hash digest, you can see it is exactly equivalent to the [corresponding take with manual bit-shifting hacks](http://coliru.stacked-crooked.com/a/54beaa05356292ac) – sehe Feb 15 '19 at 15:27
  • @Shmwel look at existing answers that employ Json or Boost Serialization with Asio. – sehe Feb 15 '19 at 15:28
  • @sehe You are shouting at me :D My intention was to show OP the need of some serialization method to achive his goal. I have to admit that my solution was overkill. `pair` as "pod" can be stored directly into vector. – rafix07 Feb 15 '19 at 18:04
  • Nah I just didn't realize what bold looked like :) I usually have this `**[Live On Coliru]...` riff (muscle memory) so the `**` comes automatic. – sehe Feb 15 '19 at 18:27