summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp')
-rw-r--r--cpp/object.hpp78
-rw-r--r--cpp/type/array.hpp10
-rw-r--r--cpp/type/boolean.hpp6
-rw-r--r--cpp/type/float.hpp18
-rw-r--r--cpp/type/integer.hpp90
-rw-r--r--cpp/type/map.hpp32
-rw-r--r--cpp/type/nil.hpp14
-rw-r--r--cpp/type/raw.hpp24
-rw-r--r--cpp/type/tuple.hpp.erb99
-rw-r--r--cpp/unpack.hpp7
10 files changed, 205 insertions, 173 deletions
diff --git a/cpp/object.hpp b/cpp/object.hpp
index a5e8682..8cce14c 100644
--- a/cpp/object.hpp
+++ b/cpp/object.hpp
@@ -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:
diff --git a/cpp/type/array.hpp b/cpp/type/array.hpp
index 7066703..703ac55 100644
--- a/cpp/type/array.hpp
+++ b/cpp/type/array.hpp
@@ -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 */
diff --git a/cpp/type/boolean.hpp b/cpp/type/boolean.hpp
index 0538495..e958478 100644
--- a/cpp/type/boolean.hpp
+++ b/cpp/type/boolean.hpp
@@ -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;
}
diff --git a/cpp/type/float.hpp b/cpp/type/float.hpp
index 11fa280..2178434 100644
--- a/cpp/type/float.hpp
+++ b/cpp/type/float.hpp
@@ -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 */
diff --git a/cpp/type/integer.hpp b/cpp/type/integer.hpp
index 488c9d4..f5841a6 100644
--- a/cpp/type/integer.hpp
+++ b/cpp/type/integer.hpp
@@ -22,9 +22,9 @@
#include <limits>
namespace msgpack {
-namespace type {
+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
+} // namespace type
-inline signed char& operator<< (signed char& v, object o)
- { v = detail::convert_integer<signed char>(o); return v; }
+inline signed char& operator>> (object o, signed char& v)
+ { v = type::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 short& operator>> (object o, signed short& v)
+ { v = type::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 int& operator>> (object o, signed int& v)
+ { v = type::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& operator>> (object o, signed long& v)
+ { v = type::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 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<< (unsigned char& v, object o)
- { v = detail::convert_integer<unsigned char>(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<< (unsigned short& v, object o)
- { v = detail::convert_integer<unsigned short>(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<< (unsigned int& v, object o)
- { v = detail::convert_integer<unsigned int>(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<< (unsigned long& v, object o)
- { v = detail::convert_integer<unsigned long>(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<< (unsigned long long& v, object o)
- { v = detail::convert_integer<unsigned long 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 const signed char& operator>> (const signed char& v, packer<Stream> o)
- { detail::pack_integer<signed char>(v, o); return v; }
+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 const signed short& operator>> (const signed short& v, packer<Stream> o)
- { detail::pack_integer<signed short>(v, o); return v; }
+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 const signed int& operator>> (const signed int& v, packer<Stream> o)
- { detail::pack_integer<signed int>(v, o); return v; }
+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 const signed long& operator>> (const signed long& v, packer<Stream> o)
- { detail::pack_integer<signed long>(v, o); return v; }
+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 const signed long long& operator>> (const signed long long& v, packer<Stream> o)
- { detail::pack_integer<signed long long>(v, o); return v; }
+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 const unsigned char& operator>> (const unsigned char& v, packer<Stream> o)
- { detail::pack_integer<unsigned char>(v, o); return v; }
+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 const unsigned short& operator>> (const unsigned short& v, packer<Stream> o)
- { detail::pack_integer<unsigned short>(v, o); return v; }
+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 const unsigned int& operator>> (const unsigned int& v, packer<Stream> o)
- { detail::pack_integer<unsigned int>(v, o); return v; }
+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 const unsigned long& operator>> (const unsigned long& v, packer<Stream> o)
- { detail::pack_integer<unsigned long>(v, o); return v; }
+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 const unsigned long long& operator>> (const unsigned long long& v, packer<Stream> o)
- { detail::pack_integer<unsigned long long>(v, o); return v; }
+inline packer<Stream>& operator<< (packer<Stream>& o, const unsigned long long& v)
+ { type::detail::pack_integer<unsigned long long>(v, o); return o; }
-} // namespace type
} // namespace msgpack
#endif /* msgpack/type/integer.hpp */
diff --git a/cpp/type/map.hpp b/cpp/type/map.hpp
index 1efecec..1d5e054 100644
--- a/cpp/type/map.hpp
+++ b/cpp/type/map.hpp
@@ -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 */
diff --git a/cpp/type/nil.hpp b/cpp/type/nil.hpp
index 73cedb4..ab0c363 100644
--- a/cpp/type/nil.hpp
+++ b/cpp/type/nil.hpp
@@ -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 */
diff --git a/cpp/type/raw.hpp b/cpp/type/raw.hpp
index 8767238..14e52f4 100644
--- a/cpp/type/raw.hpp
+++ b/cpp/type/raw.hpp
@@ -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 */
diff --git a/cpp/type/tuple.hpp.erb b/cpp/type/tuple.hpp.erb
index 2a8a2dd..c54739a 100644
--- a/cpp/type/tuple.hpp.erb
+++ b/cpp/type/tuple.hpp.erb
@@ -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 */
-
diff --git a/cpp/unpack.hpp b/cpp/unpack.hpp
index 07c52e7..de613a4 100644
--- a/cpp/unpack.hpp
+++ b/cpp/unpack.hpp
@@ -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)
{