| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 |
- //
- // json_tuple_binder.hpp
- // json
- //
- // Created by Sam Jaffe on 4/23/16.
- //
- #pragma once
- 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 json::malformed_json_exception(std::string("Expected an object type for binding to ") + typeid(T).name());
- }
- }
-
- 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 json::unterminated_json_exception("Reached end of parse string without finding array end");
- }
-
- 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;
- };
- } }
|