Created
October 28, 2018 14:01
-
-
Save varphone/0b281e8b933e956a16369740378c216f to your computer and use it in GitHub Desktop.
vector-add-assign-op.cc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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