LoginSignup
0
1

More than 1 year has passed since last update.

C++にpackが欲しい

Posted at

書きかけ及びパラメータパックの習作
std::formatという安全なsprintfがあるならばP言語のpack/unpackも比較的安全に作れるのでは?という思いつき
(boostのiotreams使えばいいという話もある)

cpp20
#include <iostream>
#include <vector>
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <string>
#include <type_traits>
#include <concepts>
#include <array>

template<typename T>
concept Serializable = std::copyable<T> && !std::is_pointer_v<T>;

template<Serializable T>
std::vector<uint8_t> _pack(T num){
  std::vector<uint8_t> r(sizeof(num));
  memcpy(r.data(), &num, sizeof(num));
  return r;
}

template<Serializable T, std::integral Tn, Tn m>
std::vector<uint8_t> _pack(T (&n)[m]){
    auto size = sizeof(n);
    std::vector<uint8_t> r(size);
    memcpy(r.data(), n, size);
    return r;
}

template<std::integral T>
struct rev{
    const T &val;
};

template<std::integral T>
std::vector<uint8_t> _pack(rev<T> n){
    auto size = sizeof(T);
    std::vector<uint8_t> r(size);
    auto b = _pack(n.val);
    for(size_t i = 0; i < size; i++){
        r[i] = b[size-i-1];
    }
    return r;
}

std::vector<uint8_t> _pack(std::vector<uint8_t> a){ return a; }

std::vector<uint8_t> _pack(std::string_view s){
  std::vector<uint8_t> r(s.size()+1);
  memcpy(r.data(), s.data(), s.size());
  r[s.size()] = 0;
  return r;
}

template<typename ... T>
std::vector<uint8_t> pack(T ...args){
    std::vector<std::vector<uint8_t>> tmp{ _pack(args)... };
    size_t total_size = 0;
    for(const auto& it : tmp){ total_size += size(it);  }

    std::vector<uint8_t> result(total_size);
    size_t offset = 0;
    uint8_t* ptr = result.data();
    for(const auto& it : tmp){
        memcpy(ptr + offset, it.data(), size(it));
        offset += size(it);
    }
    return result;
}

void display(std::vector<uint8_t> buf){
    printf("length: %zu\n", buf.size());
    for(const uint8_t& b : buf)
      printf("%02X ", b);
    puts("");
}

int main(){
    uint16_t a[] = {1,2,3,4,0xFFEF};
    auto b = pack(std::to_array(a), "1234567", rev<uint32_t>{0x123456}, uint32_t(0x987654));
    display(b);
}
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1