| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- //
- // 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 <vector>
- namespace json { namespace binder {
- template <typename T> class tuple_binder : public binder_impl<T> {
- public:
- virtual binder_impl<T> * clone() const override {
- return new tuple_binder(*this);
- }
- tuple_binder & operator()(binder<T> 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<binder<T>>::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 <typename E> tuple_binder & operator()(E T::*p) {
- return operator()(binder<T>(new direct_binder<T, E>(p)));
- }
- private:
- std::vector<binder<T>> members;
- };
- }}
|