Skip to content

Instantly share code, notes, and snippets.

@pmor13
Last active August 29, 2015 14:18
Show Gist options
  • Save pmor13/b89c1aa77bd263b3cc6a to your computer and use it in GitHub Desktop.
Save pmor13/b89c1aa77bd263b3cc6a to your computer and use it in GitHub Desktop.
Attempt to model generic container which can be used as type of packet field. Compatible with g++ 4.9.2 and VS10.
#include <cassert>
#include <iostream>
#include <cstring>
namespace ns_container {
// Container definition
typedef unsigned char element_type;
template <size_t N> struct container {
static const int capacity = N;
element_type data[N];
size_t size;
signed max_value;
public:
// Writing & Reading
template<typename T> inline friend container &operator<<(container &dst, const T& src) {
assert(src.size);
assert(src.capacity >= src.size);
assert(dst.capacity >= dst.size);
assert(dst.capacity >= dst.size + src.size);
std::memmove(&dst.data[0] + dst.size, &src.data, src.size * sizeof(element_type));
dst.size += src.size;
return dst;
}
template<typename T> inline friend container &operator>>(container &dst, T& src) {
assert(src.capacity >= src.size);
assert(dst.capacity >= dst.size);
assert(dst.size >= src.size);
if (src.max_value) {
assert(!src.size);
// Probe to find variadic size
while (dst.data[src.size] < src.max_value) ++src.size;
}
else assert(!src.max_value);
dst.size -= src.size;
std::memmove(&src.data, &dst.data, src.size * sizeof(element_type));
std::memmove(&dst.data, &dst.data[0] + src.size, dst.size * sizeof(element_type));
return dst;
}
template<typename T> inline friend const bool operator==(const container &dst, const T &src) {
assert(src.capacity >= src.size);
assert(dst.capacity >= dst.size);
return dst.size != src.size ? false : !std::memcmp(&dst.data, &src.data, dst.size);
}
template<typename T> inline friend const bool operator!=(const container &dst, const T &src) {
return !(dst == src);
}
inline friend std::ostream &operator<<(std::ostream &os, const container& that) {
if (!that.size) os << "empty\n";
os << "[";
size_t last = that.size - 1;
for (size_t idx = 0; idx < that.size; ++idx) {
os << static_cast<unsigned int>(that.data[idx]);
if (idx != last) os << ", ";
}
os << "]";
return os;
}
};
typedef struct container<1> cter_1_t;
typedef struct container<2> cter_2_t;
typedef struct container<16> cter_16_t;
typedef struct container<64> cter_64_t;
typedef struct container<256> cter_256_t;
typedef struct container<2048> cter_2048_t;
typedef struct container<2084> cter_2084_t;
typedef struct container<4096> cter_4096_t;
typedef struct container<65536> cter_65536_t;
} // namespace
// Compile with: g++ container_g++492.cpp
int main(int argc, char* argv[]) {
using namespace ns_container;
cter_2084_t Packet = {0};
//Transmitter
#define INIT(...) {{__VA_ARGS__}, sizeof((unsigned char[]){__VA_ARGS__})} /* Only for g++ */
// cter_16_t dpa_address = INIT(0, 1, 2, 3, 4);
{cter_16_t dpa_address = {{0, 1, 2, 3, 4}, 5};
cter_1_t dla_address = {{32}, 1};
cter_16_t spa_address = {{0, 1, 2}, 3};
cter_1_t sla_address = {{33}, 1};
cter_2048_t user_data = {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, 10};
cter_2_t crc = {{255, 255}, 2};
Packet << dpa_address << dla_address << spa_address << sla_address << user_data << crc;
std::cout << Packet << std::endl;}
//Receiver
{cter_16_t dpa_address = {{0}, 0, 32}; // 32 is max value
cter_1_t dla_address = {{0}, 1};
cter_16_t spa_address = {{0}, 0, 32};
cter_1_t sla_address = {{0}, 1};
cter_2048_t user_data = {{0}, 10};
cter_2_t crc = {{0}, 2};
Packet >> dpa_address >> dla_address >> spa_address >> sla_address >> user_data >> crc;
std::cout << dpa_address << std::endl;
std::cout << dla_address << std::endl;
std::cout << spa_address << std::endl;
std::cout << sla_address << std::endl;
std::cout << user_data << std::endl;
std::cout << crc << std::endl;}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment