lang/c/msgpack: C++ binding: reexamined global operators

git-svn-id: file:///Users/frsyuki/project/msgpack-git/svn/x@72 5a5092ae-2292-43ba-b2d5-dcab9c1a2731
This commit is contained in:
frsyuki 2009-02-15 09:09:58 +00:00
parent f4a6d7faa1
commit 2c7f0b2b1a
10 changed files with 241 additions and 209 deletions

View File

@ -31,6 +31,18 @@ namespace msgpack {
class type_error : public std::bad_cast { };
namespace type {
static const unsigned char NIL = 0x01;
static const unsigned char BOOLEAN = 0x02;
static const unsigned char POSITIVE_INTEGER = 0x03;
static const unsigned char NEGATIVE_INTEGER = 0x04;
static const unsigned char DOUBLE = 0x05;
static const unsigned char RAW = 0x06;
static const unsigned char ARRAY = 0x07;
static const unsigned char MAP = 0x08;
}
struct object {
unsigned char type;
union {
@ -50,6 +62,11 @@ struct object {
template <typename T>
operator T() { T v; convert(v, *this); return v; };
template <typename T>
T as() { T v; convert(v, *this); return v; }
bool is_nil() { return type == type::NIL; }
};
std::ostream& operator<< (std::ostream& s, const object o);
@ -58,53 +75,36 @@ bool operator==(const object x, const object y);
inline bool operator!=(const object x, const object y) { return !(x == y); }
inline object& operator<< (object& v, object o)
inline object& operator>> (object o, object& v)
{ v = o; return v; }
template <typename Stream>
const object& operator>> (const object& v, packer<Stream>& o);
packer<Stream>& operator<< (packer<Stream>& o, const object& v);
namespace type {
static const unsigned char NIL = 0x01;
static const unsigned char BOOLEAN = 0x02;
static const unsigned char POSITIVE_INTEGER = 0x03;
static const unsigned char NEGATIVE_INTEGER = 0x04;
static const unsigned char DOUBLE = 0x05;
static const unsigned char RAW = 0x06;
static const unsigned char ARRAY = 0x07;
static const unsigned char MAP = 0x08;
template <typename T>
inline T& operator<< (T& v, object o)
inline T& operator>> (object o, T& v)
{
v.msgpack_unpack(o);
return v;
}
namespace detail {
template <typename Stream, typename T>
inline void pack_copy(T v, packer<Stream>& o)
{ pack(v, o); }
}
template <typename Stream, typename T>
inline const T& operator>> (const T& v, packer<Stream>& o)
inline packer<Stream>& operator<< (packer<Stream>& o, const T& v)
{
detail::pack_copy(v.msgpack_pack(), o);
return v;
pack_copy(v.msgpack_pack(), o);
return o;
}
} // namespace type
}
template <typename T>
inline void convert(T& v, object o)
{
using namespace type;
v << o;
o >> v;
}
@ -112,7 +112,7 @@ template <typename Stream, typename T>
inline void pack(T& v, packer<Stream>& o)
{
using namespace type;
v >> o;
o << v;
}
@ -124,14 +124,20 @@ inline void pack(T& v, Stream& s)
}
template <typename Stream, typename T>
inline void pack_copy(T v, packer<Stream>& o)
{
pack(v, o);
}
template <typename Stream>
const object& operator>> (const object& v, packer<Stream>& o)
packer<Stream>& operator<< (packer<Stream>& o, const object& v)
{
switch(v.type) {
case type::NIL:
o.pack_nil();
return v;
return o;
case type::BOOLEAN:
if(v.via.boolean) {
@ -139,7 +145,7 @@ const object& operator>> (const object& v, packer<Stream>& o)
} else {
o.pack_false();
}
return v;
return o;
case type::POSITIVE_INTEGER:
if(v.via.u64 <= (uint64_t)std::numeric_limits<uint16_t>::max()) {
@ -155,7 +161,7 @@ const object& operator>> (const object& v, packer<Stream>& o)
o.pack_uint64(v.via.u64);
}
}
return v;
return o;
case type::NEGATIVE_INTEGER:
if(v.via.i64 >= (int64_t)std::numeric_limits<int16_t>::min()) {
@ -171,11 +177,11 @@ const object& operator>> (const object& v, packer<Stream>& o)
o.pack_int64(v.via.i64);
}
}
return v;
return o;
case type::RAW:
o.pack_raw(v.via.ref.ptr, v.via.ref.size);
return v;
return o;
case type::ARRAY:
o.pack_array(v.via.container.size);
@ -184,7 +190,7 @@ const object& operator>> (const object& v, packer<Stream>& o)
p < pend; ++p) {
*p >> o;
}
return v;
return o;
// FIXME loop optimiziation
case type::MAP:
@ -195,7 +201,7 @@ const object& operator>> (const object& v, packer<Stream>& o)
*p >> o; ++p;
*p >> o; ++p;
}
return v;
return o;
// FIXME loop optimiziation
default:

View File

@ -22,13 +22,12 @@
#include <vector>
namespace msgpack {
namespace type {
template <typename T>
inline std::vector<T> operator<< (std::vector<T>& v, object o)
inline std::vector<T> operator>> (object o, std::vector<T>& v)
{
if(o.type != ARRAY) { throw type_error(); }
if(o.type != type::ARRAY) { throw type_error(); }
v.resize(o.via.container.size);
object* p(o.via.container.ptr);
object* const pend(o.via.container.ptr + o.via.container.size);
@ -41,18 +40,17 @@ inline std::vector<T> operator<< (std::vector<T>& v, object o)
template <typename Stream, typename T>
inline const std::vector<T>& operator>> (const std::vector<T>& v, packer<Stream>& o)
inline packer<Stream>& operator<< (packer<Stream>& o, const std::vector<T>& v)
{
o.pack_array(v.size());
for(typename std::vector<T>::const_iterator it(v.begin()), it_end(v.end());
it != it_end; ++it) {
pack(*it, o);
}
return v;
return o;
}
} // namespace type
} // namespace msgpack
#endif /* msgpack/type/array.hpp */

View File

@ -25,7 +25,7 @@ namespace msgpack {
namespace type {
inline bool& operator<< (bool& v, object o)
inline bool& operator>> (object o, bool& v)
{
if(o.type != BOOLEAN) { throw type_error(); }
v = o.via.boolean;
@ -34,11 +34,11 @@ inline bool& operator<< (bool& v, object o)
template <typename Stream>
inline const bool& operator>> (const bool& v, packer<Stream> o)
inline packer<Stream>& operator<< (packer<Stream>& o, const bool& v)
{
if(v) { o.pack_true(); }
else { o.pack_false(); }
return v;
return o;
}

View File

@ -22,45 +22,43 @@
#include <vector>
namespace msgpack {
namespace type {
// FIXME check overflow, underflow
inline float& operator<< (float& v, object o)
inline float& operator>> (object o, float& v)
{
if(o.type != DOUBLE) { throw type_error(); }
if(o.type != type::DOUBLE) { throw type_error(); }
v = o.via.dec;
return v;
}
template <typename Stream>
inline const float& operator>> (const float& v, packer<Stream> o)
inline packer<Stream>& operator<< (packer<Stream>& o, const float& v)
{
o.pack_float(v);
return v;
return o;
}
inline double& operator<< (double& v, object o)
inline double& operator>> (object o, double& v)
{
if(o.type != DOUBLE) { throw type_error(); }
if(o.type != type::DOUBLE) { throw type_error(); }
v = o.via.dec;
return v;
}
template <typename Stream>
inline const double& operator>> (const double& v, packer<Stream> o)
inline packer<Stream>& operator<< (packer<Stream>& o, const double& v)
{
o.pack_double(v);
return v;
return o;
}
} // namespace type
} // namespace msgpack
#endif /* msgpack/type/float.hpp */

View File

@ -22,9 +22,9 @@
#include <limits>
namespace msgpack {
namespace type {
namespace detail {
template <typename T, bool Signed>
struct convert_integer_sign;
@ -32,11 +32,11 @@ namespace detail {
template <typename T>
struct convert_integer_sign<T, true> {
static inline T convert(object o) {
if(o.type == POSITIVE_INTEGER) {
if(o.type == type::POSITIVE_INTEGER) {
if(o.via.u64 > (uint64_t)std::numeric_limits<T>::max())
{ throw type_error(); }
return o.via.u64;
} else if(o.type == NEGATIVE_INTEGER) {
} else if(o.type == type::NEGATIVE_INTEGER) {
if(o.via.i64 < (int64_t)-std::numeric_limits<T>::max())
{ throw type_error(); }
return o.via.i64;
@ -48,7 +48,7 @@ namespace detail {
template <typename T>
struct convert_integer_sign<T, false> {
static inline T convert(object o) {
if(o.type == POSITIVE_INTEGER) {
if(o.type == type::POSITIVE_INTEGER) {
if(o.via.u64 > (uint64_t)std::numeric_limits<T>::max())
{ throw type_error(); }
return o.via.u64;
@ -160,83 +160,83 @@ namespace detail {
}
} // namespace detail
inline signed char& operator<< (signed char& v, object o)
{ v = detail::convert_integer<signed char>(o); return v; }
inline signed short& operator<< (signed short& v, object o)
{ v = detail::convert_integer<signed short>(o); return v; }
inline signed int& operator<< (signed int& v, object o)
{ v = detail::convert_integer<signed int>(o); return v; }
inline signed long& operator<< (signed long& v, object o)
{ v = detail::convert_integer<signed long>(o); return v; }
inline signed long long& operator<< (signed long long& v, object o)
{ v = detail::convert_integer<signed long long>(o); return v; }
inline unsigned char& operator<< (unsigned char& v, object o)
{ v = detail::convert_integer<unsigned char>(o); return v; }
inline unsigned short& operator<< (unsigned short& v, object o)
{ v = detail::convert_integer<unsigned short>(o); return v; }
inline unsigned int& operator<< (unsigned int& v, object o)
{ v = detail::convert_integer<unsigned int>(o); return v; }
inline unsigned long& operator<< (unsigned long& v, object o)
{ v = detail::convert_integer<unsigned long>(o); return v; }
inline unsigned long long& operator<< (unsigned long long& v, object o)
{ v = detail::convert_integer<unsigned long long>(o); return v; }
template <typename Stream>
inline const signed char& operator>> (const signed char& v, packer<Stream> o)
{ detail::pack_integer<signed char>(v, o); return v; }
template <typename Stream>
inline const signed short& operator>> (const signed short& v, packer<Stream> o)
{ detail::pack_integer<signed short>(v, o); return v; }
template <typename Stream>
inline const signed int& operator>> (const signed int& v, packer<Stream> o)
{ detail::pack_integer<signed int>(v, o); return v; }
template <typename Stream>
inline const signed long& operator>> (const signed long& v, packer<Stream> o)
{ detail::pack_integer<signed long>(v, o); return v; }
template <typename Stream>
inline const signed long long& operator>> (const signed long long& v, packer<Stream> o)
{ detail::pack_integer<signed long long>(v, o); return v; }
template <typename Stream>
inline const unsigned char& operator>> (const unsigned char& v, packer<Stream> o)
{ detail::pack_integer<unsigned char>(v, o); return v; }
template <typename Stream>
inline const unsigned short& operator>> (const unsigned short& v, packer<Stream> o)
{ detail::pack_integer<unsigned short>(v, o); return v; }
template <typename Stream>
inline const unsigned int& operator>> (const unsigned int& v, packer<Stream> o)
{ detail::pack_integer<unsigned int>(v, o); return v; }
template <typename Stream>
inline const unsigned long& operator>> (const unsigned long& v, packer<Stream> o)
{ detail::pack_integer<unsigned long>(v, o); return v; }
template <typename Stream>
inline const unsigned long long& operator>> (const unsigned long long& v, packer<Stream> o)
{ detail::pack_integer<unsigned long long>(v, o); return v; }
} // namespace type
inline signed char& operator>> (object o, signed char& v)
{ v = type::detail::convert_integer<signed char>(o); return v; }
inline signed short& operator>> (object o, signed short& v)
{ v = type::detail::convert_integer<signed short>(o); return v; }
inline signed int& operator>> (object o, signed int& v)
{ v = type::detail::convert_integer<signed int>(o); return v; }
inline signed long& operator>> (object o, signed long& v)
{ v = type::detail::convert_integer<signed long>(o); return v; }
inline signed long long& operator>> (object o, signed long long& v)
{ v = type::detail::convert_integer<signed long long>(o); return v; }
inline unsigned char& operator>> (object o, unsigned char& v)
{ v = type::detail::convert_integer<unsigned char>(o); return v; }
inline unsigned short& operator>> (object o, unsigned short& v)
{ v = type::detail::convert_integer<unsigned short>(o); return v; }
inline unsigned int& operator>> (object o, unsigned int& v)
{ v = type::detail::convert_integer<unsigned int>(o); return v; }
inline unsigned long& operator>> (object o, unsigned long& v)
{ v = type::detail::convert_integer<unsigned long>(o); return v; }
inline unsigned long long& operator>> (object o, unsigned long long& v)
{ v = type::detail::convert_integer<unsigned long long>(o); return v; }
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const signed char& v)
{ type::detail::pack_integer<signed char>(v, o); return o; }
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const signed short& v)
{ type::detail::pack_integer<signed short>(v, o); return o; }
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const signed int& v)
{ type::detail::pack_integer<signed int>(v, o); return o; }
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const signed long& v)
{ type::detail::pack_integer<signed long>(v, o); return o; }
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const signed long long& v)
{ type::detail::pack_integer<signed long long>(v, o); return o; }
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const unsigned char& v)
{ type::detail::pack_integer<unsigned char>(v, o); return o; }
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const unsigned short& v)
{ type::detail::pack_integer<unsigned short>(v, o); return o; }
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const unsigned int& v)
{ type::detail::pack_integer<unsigned int>(v, o); return o; }
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const unsigned long& v)
{ type::detail::pack_integer<unsigned long>(v, o); return o; }
template <typename Stream>
inline packer<Stream>& operator<< (packer<Stream>& o, const unsigned long long& v)
{ type::detail::pack_integer<unsigned long long>(v, o); return o; }
} // namespace msgpack
#endif /* msgpack/type/integer.hpp */

View File

@ -23,9 +23,10 @@
#include <vector>
namespace msgpack {
namespace type {
namespace type {
template <typename K, typename V>
class assoc_vector : public std::vector< std::pair<K, V> > {};
@ -37,10 +38,13 @@ namespace detail {
};
}
} //namespace type
template <typename K, typename V>
inline assoc_vector<K,V>& operator<< (assoc_vector<K,V>& v, object o)
inline type::assoc_vector<K,V>& operator>> (object o, type::assoc_vector<K,V>& v)
{
if(o.type != MAP) { throw type_error(); }
if(o.type != type::MAP) { throw type_error(); }
v.resize(o.via.container.size);
object* p(o.via.container.ptr);
object* const pend(o.via.container.ptr + o.via.container.size);
@ -49,26 +53,27 @@ inline assoc_vector<K,V>& operator<< (assoc_vector<K,V>& v, object o)
convert(it->first, *p); ++p;
convert(it->second, *p); ++p;
}
std::sort(v.begin(), v.end(), detail::pair_first_less<K,V>());
std::sort(v.begin(), v.end(), type::detail::pair_first_less<K,V>());
return v;
}
template <typename Stream, typename K, typename V>
inline const assoc_vector<K,V>& operator>> (const assoc_vector<K,V>& v, packer<Stream>& o)
inline packer<Stream>& operator<< (packer<Stream>& o, const type::assoc_vector<K,V>& v)
{
o.pack_map(v.size());
for(typename assoc_vector<K,V>::const_iterator it(v.begin()), it_end(v.end());
for(typename type::assoc_vector<K,V>::const_iterator it(v.begin()), it_end(v.end());
it != it_end; ++it) {
pack(it->first, o);
pack(it->second, o);
}
return o;
}
template <typename K, typename V>
inline std::map<K, V> operator<< (std::map<K, V>& v, object o)
inline std::map<K, V> operator>> (object o, std::map<K, V>& v)
{
if(o.type != MAP) { throw type_error(); }
if(o.type != type::MAP) { throw type_error(); }
object* p(o.via.container.ptr);
object* const pend(o.via.container.ptr + o.via.container.size*2);
while(p < pend) {
@ -87,7 +92,7 @@ inline std::map<K, V> operator<< (std::map<K, V>& v, object o)
}
template <typename Stream, typename K, typename V>
inline const std::map<K,V>& operator>> (const std::map<K,V>& v, packer<Stream>& o)
inline packer<Stream>& operator<< (packer<Stream>& o, const std::map<K,V>& v)
{
o.pack_map(v.size());
for(typename std::map<K,V>::const_iterator it(v.begin()), it_end(v.end());
@ -95,13 +100,14 @@ inline const std::map<K,V>& operator>> (const std::map<K,V>& v, packer<Stream>&
pack(it->first, o);
pack(it->second, o);
}
return o;
}
template <typename K, typename V>
inline std::multimap<K, V> operator<< (std::multimap<K, V>& v, object o)
inline std::multimap<K, V> operator>> (object o, std::multimap<K, V>& v)
{
if(o.type != MAP) { throw type_error(); }
if(o.type != type::MAP) { throw type_error(); }
object* p(o.via.container.ptr);
object* const pend(o.via.container.ptr + o.via.container.size*2);
while(p < pend) {
@ -114,7 +120,7 @@ inline std::multimap<K, V> operator<< (std::multimap<K, V>& v, object o)
}
template <typename Stream, typename K, typename V>
inline const std::multimap<K,V>& operator>> (const std::multimap<K,V>& v, packer<Stream>& o)
inline packer<Stream>& operator<< (packer<Stream>& o, const std::multimap<K,V>& v)
{
o.pack_multimap(v.size());
for(typename std::multimap<K,V>::const_iterator it(v.begin()), it_end(v.end());
@ -122,10 +128,10 @@ inline const std::multimap<K,V>& operator>> (const std::multimap<K,V>& v, packer
pack(it->first, o);
pack(it->second, o);
}
return o;
}
} // namespace type
} // namespace msgpack
#endif /* msgpack/type/map.hpp */

View File

@ -21,26 +21,28 @@
#include "msgpack/object.hpp"
namespace msgpack {
namespace type {
namespace type {
struct nil { };
inline nil& operator<< (nil& v, object o)
} // namespace type
inline type::nil& operator>> (object o, type::nil& v)
{
if(o.type != NIL) { throw type_error(); }
if(o.type != type::NIL) { throw type_error(); }
return v;
}
template <typename Stream>
inline const nil& operator>> (const nil& v, packer<Stream>& o)
inline packer<Stream>& operator<< (packer<Stream>& o, const type::nil& v)
{
o.pack_nil();
return v;
return o;
}
} // namespace type
} // namespace msgpack
#endif /* msgpack/type/nil.hpp */

View File

@ -23,8 +23,8 @@
#include <string>
namespace msgpack {
namespace type {
namespace type {
struct raw_ref {
raw_ref() : ptr(NULL), size(0) {}
@ -58,41 +58,43 @@ struct raw_ref {
}
};
inline raw_ref& operator<< (raw_ref& v, object o)
} // namespace type
inline type::raw_ref& operator>> (object o, type::raw_ref& v)
{
if(o.type != RAW) { throw type_error(); }
if(o.type != type::RAW) { throw type_error(); }
v.ptr = o.via.ref.ptr;
v.size = o.via.ref.size;
return v;
}
inline std::string& operator<< (std::string& v, object o)
inline std::string& operator>> (object o, std::string& v)
{
raw_ref r;
r << o;
type::raw_ref r;
o >> r;
v.assign(r.ptr, r.size);
return v;
}
template <typename Stream>
inline const raw_ref& operator>> (const raw_ref& v, packer<Stream>& o)
inline packer<Stream>& operator<< (packer<Stream>& o, const type::raw_ref& v)
{
o.pack_raw(v.ptr, v.size);
return v;
return o;
}
template <typename Stream>
inline const std::string& operator>> (const std::string& v, packer<Stream>& o)
inline packer<Stream>& operator<< (packer<Stream>& o, const std::string& v)
{
o.pack_raw(v.data(), v.size());
return v;
return o;
}
} // namespace type
} // namespace msgpack
#endif /* msgpack/type/raw.hpp */

View File

@ -21,15 +21,14 @@
#include "msgpack/object.hpp"
namespace msgpack {
namespace type {
namespace type {
// FIXME operator==
// FIXME operator!=
<% GENERATION_LIMIT = 15 %>
template < typename A0 <%1.upto(GENERATION_LIMIT+1) {|i|%>, typename A<%=i%> = void<%}%> >
template <typename A0 = void<%1.upto(GENERATION_LIMIT+1) {|i|%>, typename A<%=i%> = void<%}%>>
struct tuple;
template <typename Tuple, int N>
@ -60,9 +59,9 @@ private:
<%0.upto(GENERATION_LIMIT) {|i|%>
<%0.upto(i) {|j|%>
template < typename A0 <%1.upto(i) {|k|%>, typename A<%=k%> <%}%>>
struct tuple_type<tuple<A0 <%1.upto(i) {|k|%>, A<%=k%> <%}%>>, <%=j%>> : tuple_element<A<%=j%>> {
tuple_type(tuple<A0 <%1.upto(i) {|k|%>, A<%=k%> <%}%>>& x) : tuple_element<A<%=j%>>(x.a<%=j%>) {}
template <typename A0<%1.upto(i) {|k|%>, typename A<%=k%><%}%>>
struct tuple_type<tuple<A0<%1.upto(i) {|k|%>, A<%=k%><%}%>>, <%=j%>> : tuple_element<A<%=j%>> {
tuple_type(tuple<A0<%1.upto(i) {|k|%>, A<%=k%> <%}%>>& x) : tuple_element<A<%=j%>>(x.a<%=j%>) {}
};
<%}%>
<%}%>
@ -70,46 +69,57 @@ struct tuple_type<tuple<A0 <%1.upto(i) {|k|%>, A<%=k%> <%}%>>, <%=j%>> : tuple_e
<%0.upto(GENERATION_LIMIT) {|i|%>
<%0.upto(i) {|j|%>
template < typename A0 <%1.upto(i) {|k|%>, typename A<%=k%> <%}%>>
struct const_tuple_type<tuple<A0 <%1.upto(i) {|k|%>, A<%=k%> <%}%>>, <%=j%>> : const_tuple_element<A<%=j%>> {
const_tuple_type(const tuple<A0 <%1.upto(i) {|k|%>, A<%=k%> <%}%>>& x) : const_tuple_element<A<%=j%>>(x.a<%=j%>) {}
template <typename A0<%1.upto(i) {|k|%>, typename A<%=k%><%}%>>
struct const_tuple_type<tuple<A0<%1.upto(i) {|k|%>, A<%=k%><%}%>>, <%=j%>> : const_tuple_element<A<%=j%>> {
const_tuple_type(const tuple<A0<%1.upto(i) {|k|%>, A<%=k%><%}%>>& x) : const_tuple_element<A<%=j%>>(x.a<%=j%>) {}
};
<%}%>
<%}%>
<%0.upto(GENERATION_LIMIT) {|i|%>
template < typename A0 <%1.upto(i) {|j|%>, typename A<%=j%> <%}%>>
tuple< A0 <%1.upto(i) {|j|%>, A<%=j%> <%}%>> make_tuple(const A0& a0 <%1.upto(i) {|j|%>, const A<%=j%>& a<%=j%><%}%>)
template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> make_tuple(const A0& a0<%1.upto(i) {|j|%>, const A<%=j%>& a<%=j%><%}%>)
{
return tuple< A0 <%1.upto(i) {|j|%>, A<%=j%> <%}%>>(a0 <%1.upto(i) {|j|%>, a<%=j%><%}%>);
return tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>(a0<%1.upto(i) {|j|%>, a<%=j%><%}%>);
}
<%}%>
template <>
struct tuple<> {
};
<%0.upto(GENERATION_LIMIT) {|i|%>
template < typename A0 <%1.upto(i) {|j|%>, typename A<%=j%> <%}%>>
struct tuple<A0 <%1.upto(i) {|j|%>, A<%=j%> <%}%>> {
template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
struct tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>> {
tuple() {}
tuple(const A0& _a0 <%1.upto(i) {|j|%>, const A<%=j%>& _a<%=j%><%}%>) :
tuple(const A0& _a0<%1.upto(i) {|j|%>, const A<%=j%>& _a<%=j%><%}%>) :
a0(_a0) <%1.upto(i) {|j|%>, a<%=j%>(_a<%=j%>)<%}%> {}
tuple(object o) { convert(*this, o); }
template <int N> typename tuple_type<tuple<A0 <%1.upto(i) {|j|%>, A<%=j%> <%}%>>, N>::type& get()
{ return tuple_type<tuple<A0 <%1.upto(i) {|j|%>, A<%=j%> <%}%>>, N>(*this).get(); }
template <int N> const typename const_tuple_type<tuple<A0 <%1.upto(i) {|j|%>, A<%=j%> <%}%>>, N>::type& get() const
{ return const_tuple_type<tuple<A0 <%1.upto(i) {|j|%>, A<%=j%> <%}%>>, N>(*this).get(); }
template <int N> typename tuple_type<tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>, N>::type& get()
{ return tuple_type<tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>, N>(*this).get(); }
template <int N> const typename const_tuple_type<tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>, N>::type& get() const
{ return const_tuple_type<tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>, N>(*this).get(); }
<%0.upto(i) {|j|%>
A<%=j%> a<%=j%>;<%}%>
};
<%}%>
} // namespace type
inline type::tuple<>& operator>> (
object o,
type::tuple<>& v) {
if(o.type != type::ARRAY) { throw type_error(); }
return v;
}
<%0.upto(GENERATION_LIMIT) {|i|%>
template < typename A0 <%1.upto(i) {|j|%>, typename A<%=j%> <%}%>>
tuple<A0 <%1.upto(i) {|j|%>, A<%=j%> <%}%>>& operator<< (
tuple<A0 <%1.upto(i) {|j|%>, A<%=j%> <%}%>>& v,
object o) {
if(o.type != ARRAY) { throw type_error(); }
template <typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& operator>> (
object o,
type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& v) {
if(o.type != type::ARRAY) { throw type_error(); }
if(o.via.container.size < <%=i+1%>) { throw type_error(); }
<%0.upto(i) {|j|%>
convert<A<%=j%>>(v.template get<<%=j%>>(), o.via.container.ptr[<%=j%>]);<%}%>
@ -118,6 +128,26 @@ tuple<A0 <%1.upto(i) {|j|%>, A<%=j%> <%}%>>& operator<< (
<%}%>
template <typename Stream>
const packer<Stream>& operator<< (
packer<Stream>& o,
const type::tuple<>& v) {
o.pack_array(0);
return o;
}
<%0.upto(GENERATION_LIMIT) {|i|%>
template <typename Stream, typename A0<%1.upto(i) {|j|%>, typename A<%=j%><%}%>>
const packer<Stream>& operator<< (
packer<Stream>& o,
const type::tuple<A0<%1.upto(i) {|j|%>, A<%=j%><%}%>>& v) {
o.pack_array(<%=i+1%>);
<%0.upto(i) {|j|%>
pack(v.template get<<%=j%>>(), o);<%}%>
return o;
}
<%}%>
// FIXME
/*
template <typename A0, typename A1 = void, typename A2 = void>
@ -128,7 +158,7 @@ struct tuple_just<A0> {
A0 a0;
static inline void convert(object o, tuple_just<A0>& v)
{
if(o.type != ARRAY) { throw type_error(); }
if(o.type != type::ARRAY) { throw type_error(); }
if(o.v.container.size != 1) { throw type_error(); }
msgpack::convert<A0>(o.v.container.ptr[0], v.a0);
}
@ -140,7 +170,7 @@ struct tuple_just<A0, A1> {
A1 a1;
static inline void convert(object o, tuple_just<A0, A1>& v)
{
if(o.type != ARRAY) { throw type_error(); }
if(o.type != type::ARRAY) { throw type_error(); }
if(o.v.container.size != 2) { throw type_error(); }
msgpack::convert<A0>(o.v.container.ptr[0], v.a0);
msgpack::convert<A1>(o.v.container.ptr[1], v.a1);
@ -149,24 +179,7 @@ struct tuple_just<A0, A1> {
*/
<%0.upto(GENERATION_LIMIT) {|i|%>
template < typename Stream , typename A0 <%1.upto(i) {|j|%>, typename A<%=j%> <%}%>>
const tuple<A0 <%1.upto(i) {|j|%>, A<%=j%> <%}%>>& operator>> (
const tuple<A0 <%1.upto(i) {|j|%>, A<%=j%> <%}%>>& v,
packer<Stream> o) {
o.pack_array(<%=i+1%>);
<%0.upto(i) {|j|%>
pack(v.template get<<%=j%>>(), o);<%}%>
return v;
}
<%}%>
} // namespace type
} // namespace msgpack
#endif /* msgpack/type/tuple.hpp */

View File

@ -124,6 +124,10 @@ public:
// Note that reset() leaves non-parsed buffer.
void remove_nonparsed_buffer();
/*! skip specified size of non-parsed buffer, leaving the buffer */
// Note the size must be smaller than nonparsed_size()
void skip_nonparsed_buffer(size_t len);
private:
char* m_buffer;
size_t m_used;
@ -177,6 +181,9 @@ inline size_t unpacker::parsed_size() const
inline void unpacker::remove_nonparsed_buffer()
{ m_used = m_off; }
inline void unpacker::skip_nonparsed_buffer(size_t len)
{ m_off += len; }
inline object unpack(const char* data, size_t len, zone& z, size_t* off = NULL)
{