// // json_tuple_binder.hpp // json // // Created by Sam Jaffe on 4/23/16. // #pragma once #include "json_binder.hpp" #include "json_direct_binder.hpp" #include 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, parser::options opts) const override { const char ch = json::helper::get_next_element(data); if (ch == '[') { parse_tuple(object, ++data, opts); } else { throw not_an_array_exception(object); } } virtual void write(T const & val, std::ostream & data) const override { data << '['; typename std::vector>::const_iterator it = members.begin(), end = members.end(); if (it != end) { it->write(val, data); for (++it; it != end; ++it) { data << ','; it->write(val, data); } } data << ']'; } void parse_tuple(T & object, char const *& data, parser::options opts) const { auto it = members.begin(); while (*data && *data != ']' && it != members.end()) { it->parse(object, data, opts); 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 != ']') throw json::malformed_json_exception{ "Parsed every tuple element, but did not reach end"}; else if (*data) ++data; else throw unterminated_json_array(); } template tuple_binder & operator()(E T::*p) { return operator()(binder(new direct_binder(p))); } private: std::vector> members; }; }}