Hideaki Tai / msgpack-embedded

Dependents:   hello_message_pack

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers array_ref.hpp Source File

array_ref.hpp

00001 //
00002 // MessagePack for C++ static resolution routine
00003 //
00004 // Copyright (C) 2008-2009 FURUHASHI Sadayuki
00005 //
00006 //    Distributed under the Boost Software License, Version 1.0.
00007 //    (See accompanying file LICENSE_1_0.txt or copy at
00008 //    http://www.boost.org/LICENSE_1_0.txt)
00009 //
00010 #ifndef MSGPACK_TYPE_ARRAY_REF_HPP
00011 #define MSGPACK_TYPE_ARRAY_REF_HPP
00012 
00013 #include "msgpack/versioning.hpp"
00014 #include "msgpack/adaptor/adaptor_base.hpp"
00015 #include "msgpack/adaptor/check_container_size.hpp"
00016 #include <cstring>
00017 #include <string>
00018 
00019 namespace msgpack {
00020 
00021 /// @cond
00022 MSGPACK_API_VERSION_NAMESPACE(v1) {
00023 /// @endcond
00024 
00025 namespace type {
00026 
00027 template <typename T>
00028 struct array_ref {
00029     array_ref() : data(nullptr) {}
00030     array_ref(T& t) : data(&t) {}
00031 
00032     T* data;
00033 
00034     template <typename U>
00035     bool operator==(array_ref<U> const& t) const {
00036         return *data == *t.data;
00037     }
00038     template <typename U>
00039     bool operator!=(array_ref<U> const& t) const {
00040         return !(*data == *t.data);
00041     }
00042     template <typename U>
00043     bool operator< (array_ref<U> const& t) const
00044     {
00045         return *data < *t.data;
00046     }
00047     template <typename U>
00048     bool operator> (array_ref<U> const& t) const
00049     {
00050         return *t.data < *data;
00051     }
00052     template <typename U>
00053     bool operator<= (array_ref<U> const& t) const
00054     {
00055         return !(*t.data < *data);
00056     }
00057     template <typename U>
00058     bool operator>= (array_ref<U> const& t) const
00059     {
00060         return !(*data < *t.data);
00061     }
00062 };
00063 
00064 template <typename T>
00065 inline array_ref<T const> make_array_ref(T const& t) {
00066     return array_ref<T const>(t);
00067 }
00068 
00069 template <typename T>
00070 inline array_ref<T> make_array_ref(T& t) {
00071     return array_ref<T>(t);
00072 }
00073 
00074 
00075 } // namespace type
00076 
00077 namespace adaptor {
00078 
00079 template <typename T>
00080 struct convert<msgpack::type::array_ref<T> > {
00081     msgpack::object const& operator()(msgpack::object const& o, msgpack::type::array_ref<T>& v) const {
00082         if (!v.data) { throw msgpack::type_error(); }
00083         if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
00084         if (v.data->size() < o.via.bin.size) { throw msgpack::type_error(); }
00085         if (o.via.array.size > 0) {
00086             msgpack::object* p = o.via.array.ptr;
00087             msgpack::object* const pend = o.via.array.ptr + o.via.array.size;
00088             typename T::iterator it = v.data->begin();
00089             do {
00090                 p->convert(*it);
00091                 ++p;
00092                 ++it;
00093             } while(p < pend);
00094         }
00095         return o;
00096     }
00097 };
00098 
00099 template <typename T>
00100 struct convert<msgpack::type::array_ref<std::vector<T> > > {
00101     msgpack::object const& operator()(msgpack::object const& o, msgpack::type::array_ref<std::vector<T> >& v) const {
00102         if (!v.data) { throw msgpack::type_error(); }
00103         if (o.type != msgpack::type::ARRAY) { throw msgpack::type_error(); }
00104         v.data->resize(o.via.bin.size);
00105         if (o.via.array.size > 0) {
00106             msgpack::object* p = o.via.array.ptr;
00107             msgpack::object* const pend = o.via.array.ptr + o.via.array.size;
00108             typename std::vector<T>::iterator it = v.data->begin();
00109             do {
00110                 p->convert(*it);
00111                 ++p;
00112                 ++it;
00113             } while(p < pend);
00114         }
00115         return o;
00116     }
00117 };
00118 
00119 template <typename T>
00120 struct pack<msgpack::type::array_ref<T> > {
00121     template <typename Stream>
00122     msgpack::packer<Stream> & operator()(msgpack::packer<Stream> & o, const msgpack::type::array_ref<T>& v) const {
00123         if (!v.data) { throw msgpack::type_error(); }
00124         uint32_t size = checked_get_container_size(v.data->size());
00125         o.pack_array(size);
00126         for (typename T::const_iterator it(v.data->begin()), it_end(v.data->end());
00127             it != it_end; ++it) {
00128             o.pack(*it);
00129         }
00130         return o;
00131     }
00132 };
00133 
00134 template <typename T>
00135 struct object_with_zone<msgpack::type::array_ref<T> > {
00136     void operator()(msgpack::object::with_zone& o, const msgpack::type::array_ref<T>& v) const {
00137         if (!v.data) { throw msgpack::type_error(); }
00138         o.type = msgpack::type::ARRAY;
00139         if (v.data->empty()) {
00140             o.via.array.ptr = nullptr;
00141             o.via.array.size = 0;
00142         }
00143         else {
00144             uint32_t size = checked_get_container_size(v.data->size());
00145             msgpack::object* p = static_cast<msgpack::object*>(o.zone.allocate_align(sizeof(msgpack::object)*size));
00146             msgpack::object* const pend = p + size;
00147             o.via.array.ptr = p;
00148             o.via.array.size = size;
00149             typename T::const_iterator it(v.data->begin());
00150             do {
00151 #if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && !defined(__clang__)
00152 #pragma GCC diagnostic push
00153 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
00154 #endif // (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && !defined(__clang__)
00155                 *p = msgpack::object(*it, o.zone);
00156 #if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && !defined(__clang__)
00157 #pragma GCC diagnostic pop
00158 #endif // (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && !defined(__clang__)
00159                 ++p;
00160                 ++it;
00161             } while(p < pend);
00162         }
00163     }
00164 };
00165 
00166 } // namespace adaptor
00167 
00168 /// @cond
00169 } // MSGPACK_API_VERSION_NAMESPACE(v1)
00170 /// @endcond
00171 
00172 } // namespace msgpack
00173 
00174 #endif // MSGPACK_TYPE_ARRAY_REF_HPP