Skip to content

Instantly share code, notes, and snippets.

@varphone
Created October 28, 2018 14:01
Show Gist options
  • Save varphone/0b281e8b933e956a16369740378c216f to your computer and use it in GitHub Desktop.
Save varphone/0b281e8b933e956a16369740378c216f to your computer and use it in GitHub Desktop.
vector-add-assign-op.cc
#include <iostream>
#include <msgpack.hpp>
#include <sstream>
#include <vector>
struct PointF {
float x, y;
PointF(float x_ = 0.0f, float y_ = 0.0f) : x(x_), y(y_) {}
MSGPACK_DEFINE(x, y);
};
using Vector = std::vector<PointF>;
#if 0
template<typename ...Args>
Vector& operator += (Vector& self, Args&& ...args)
{
self.emplace_back(std::forward<Args>(args)...);
return self;
}
#endif
void operator+=(Vector &self, PointF &&val) {
self.emplace_back(val);
// return self;
}
Vector &operator+=(Vector &self, std::initializer_list<PointF> &&list) {
self.insert(self.end(), list.begin(), list.end());
return self;
}
Vector &operator<<(Vector &self, PointF &&val) {
self.emplace_back(val);
return self;
}
template <typename T, typename... Args>
class MsgVector : public std::vector<T> {
public:
using std::vector<T>::vector;
void operator+=(T &&val) { this->emplace_back(val); }
void operator+=(std::initializer_list<T> &&list) {
this->insert(this->end(), list.begin(), list.end());
}
MsgVector<T> &operator<<(T &&val) {
this->emplace_back(val);
return *this;
}
};
namespace msgpack {
MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS) {
namespace adaptor {
template <typename T>
struct pack<MsgVector<T>> {
template <typename Stream>
msgpack::packer<Stream> &operator()(msgpack::packer<Stream> &o,
MsgVector<T> const &v) const {
o.pack_array(v.size());
for (auto const &vv : v) o.pack(vv);
return o;
}
};
template <typename T>
struct convert<MsgVector<T>> {
msgpack::object const &operator()(msgpack::object const &o,
MsgVector<T> &v) const {
if (o.type != msgpack::type::ARRAY) throw msgpack::type_error();
std::cout << "size " << o.via.array.size << std::endl;
v.resize(o.via.array.size);
for (int i = 0; i < o.via.array.size; i++) {
o.via.array.ptr[i] >> v[i];
}
// v.emplace_back(o.via.array.ptr[i].as<PointF>());
return o;
}
};
template <typename T>
struct object_with_zone<MsgVector<T>> {
void operator()(msgpack::object::with_zone &o,
MsgVector<T> const &v) const {
o.type = type::ARRAY;
o.via.array.size = v.size();
if (v.size()) {
o.via.array.ptr = static_cast<msgpack::object *>(
o.zone.allocate_align(sizeof(msgpack::object) * o.via.array.size));
for (int i = 0; i < v.size(); i++)
o.via.array.ptr[i] = msgpack::object(v[i], o.zone);
}
}
};
template <>
struct pack<MsgVector<PointF>> {
template <typename Stream>
msgpack::packer<Stream> &operator()(msgpack::packer<Stream> &o,
MsgVector<PointF> const &v) const {
// packing implementation.
// o.pack_???(v.???);
o.pack_array(v.size());
for (auto const &p : v) {
o.pack(p);
// o.pack_array(2);
// o.pack_float(p.x);
// o.pack_float(p.y);
}
return o;
}
};
} // namespace adaptor
} // MSGPACK_API_VERSION_NAMESPACE(MSGPACK_DEFAULT_API_NS)
} // namespace msgpack
std::ostream &operator<<(std::ostream &os, PointF const &v) {
os << "PointF(x=" << v.x << ", y=" << v.y << ")";
return os;
}
template <typename T>
std::ostream &operator<<(std::ostream &os, MsgVector<T> const &v) {
os << "Vector[";
for (auto i = v.begin(); i != v.end(); i++)
os << (i != v.begin() ? ", " : "") << *i;
os << "]";
return os;
}
int main(int argc, char **argv) {
Vector v;
// v += PointF{1.0f, 2.0f};
v += PointF{2.0f, 3.0f};
v += {PointF(3.0f, 4.0f)};
v += {{4.0f, 5.0f}, {3.0, 5.0}};
v << PointF{1.0f, 2.0f} << PointF{1.0f, 2.0f};
std::cout << "v.size() = " << v.size() << std::endl;
MsgVector<int> vi;
vi << 1 << 2 << 3;
std::cout << "vi.size() = " << vi.size() << std::endl;
for (auto &v : vi) std::cout << "v = " << v << std::endl;
std::stringstream ss;
msgpack::pack(ss, vi);
msgpack::object_handle oh = msgpack::unpack(ss.str().data(), ss.str().size());
msgpack::object obj = oh.get();
std::cout << "obj = " << obj << std::endl;
MsgVector<PointF> vp;
vp << PointF{3.0, 4.0};
ss.str("");
ss.clear();
msgpack::pack(ss, vp);
oh = msgpack::unpack(ss.str().data(), ss.str().size());
std::cout << "obj = " << oh.get() << std::endl;
MsgVector<PointF> vp2{{1.0, 2.0}, {3.0, 4.0}};
oh.get().convert(vp2);
float xx = 1.0, yy = 2.0;
vp2 += {{xx + yy, xx * yy}, {xx, yy}, {yy, xx}};
std::cout << "vp2.size = " << vp2.size() << std::endl;
std::cout << vp2 << std::endl;
std::vector<PointF> vp3{{1.0, 2.0}, {3.0, 4.0}};
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment