// // json_tuple_binder.hpp // json // // Created by Sam Jaffe on 4/23/16. // #pragma once namespace json { namespace binder { template class tuple_binder : public binder_impl { public: virtual binder_impl* clone() const override { return new tuple_binder(*this); } tuple_binder& operator()(binder const&b) { members.push_back(b); return *this; } virtual void parse(T& object, char const*& data) const override { const char ch = json::helper::get_next_element(data); if (ch == '[') { parse_tuple(object, ++data); } else { throw json::malformed_json_exception(std::string("Expected an object type for binding to ") + typeid(T).name()); } } virtual void write(T const& val, std::string & data) const override { data += "["; for (typename std::vector>::const_iterator it = members.begin(), end = members.end(); it != end; ++it) { it->write(val, data); data += ","; } data.back() = ']'; } void parse_tuple(T& object, char const*& data) const { auto it = members.begin(); while (*data && *data != ']' && it != members.end()) { it->parse(object, data); json::helper::advance_to_boundary(']', data); ++it; } if (it != members.end()) { throw json::malformed_json_exception("Failed to parse every member of tuple"); } if (*data) ++data; else throw json::malformed_json_exception("Reached end of parse string without finding array end"); } template tuple_binder& operator()(E T::*p) { return operator()(binder(new direct_binder(p))); } private: std::vector> members; }; } }