// // json_direct_vector_binder.hpp // json // // Created by Sam Jaffe on 4/23/16. // #pragma once namespace json { namespace binder { template class non_associative_binder : public binder_impl { public: non_associative_binder(C T::*p) : ptr(p), impl(value_binder()) {} non_associative_binder(C T::*p, binder const & i) : ptr(p), impl(i) {} virtual binder_impl* clone() const override { return new non_associative_binder(*this); } virtual void parse(T& val, char const*& data, parser::options opts) const override { const char ch = json::helper::get_next_element(data); if (ch != '[') { throw json::malformed_json_exception("Expected an array type"); } ++data; V to_make; C & vec = val.*ptr; while (*data && *data != ']') { impl.parse(to_make, data, opts); vec.emplace_back(to_make); json::helper::advance_to_boundary(']', data); } if (*data) ++data; else throw json::unterminated_json_exception("Reached end of parse string without finding array end"); } virtual void write(T const& val, std::ostream & data) const override { data << '['; std::vector const & vec = val.*ptr; auto it = vec.begin(), end = vec.end(); if (it != end) { impl.write(*it, data); for (++it; it != end; ++it) { data << ","; impl.write(*it, data); } } data << ']'; } private: std::vector T::*ptr; binder impl; }; #define NON_ASSOCIATIVE_DIRECT_BINDER( C ) \ template \ class direct_binder > : \ public non_associative_binder> { \ public: \ using non_associative_binder>::non_associative_binder; \ } NON_ASSOCIATIVE_DIRECT_BINDER( std::vector ); NON_ASSOCIATIVE_DIRECT_BINDER( std::list ); NON_ASSOCIATIVE_DIRECT_BINDER( std::set ); // NON_ASSOCIATIVE_DIRECT_BINDER( std::unordered_set ); } }