json_tuple_binder.hpp 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. //
  2. // json_tuple_binder.hpp
  3. // json
  4. //
  5. // Created by Sam Jaffe on 4/23/16.
  6. //
  7. #pragma once
  8. namespace json { namespace binder {
  9. template <typename T>
  10. class tuple_binder : public binder_impl<T> {
  11. public:
  12. virtual binder_impl<T>* clone() const override { return new tuple_binder(*this); }
  13. tuple_binder& operator()(binder<T> const&b) {
  14. members.push_back(b);
  15. return *this;
  16. }
  17. virtual void parse(T& object, char const*& data) const override {
  18. const char ch = json::helper::get_next_element(data);
  19. if (ch == '[') {
  20. parse_tuple(object, ++data);
  21. } else {
  22. throw json::malformed_json_exception(std::string("Expected an object type for binding to ") + typeid(T).name());
  23. }
  24. }
  25. virtual void write(T const& val, std::string & data) const override {
  26. data += "[";
  27. for (typename std::vector<binder<T>>::const_iterator it = members.begin(),
  28. end = members.end(); it != end; ++it) {
  29. it->write(val, data);
  30. data += ",";
  31. }
  32. data.back() = ']';
  33. }
  34. void parse_tuple(T& object, char const*& data) const {
  35. auto it = members.begin();
  36. while (*data && *data != ']' && it != members.end()) {
  37. it->parse(object, data);
  38. json::helper::advance_to_boundary(']', data);
  39. ++it;
  40. }
  41. if (it != members.end()) {
  42. throw json::malformed_json_exception("Failed to parse every member of tuple");
  43. }
  44. if (*data) ++data;
  45. else throw json::malformed_json_exception("Reached end of parse string without finding array end");
  46. }
  47. template <typename E>
  48. tuple_binder& operator()(E T::*p) {
  49. return operator()(binder<T>(new direct_binder<T, E>(p)));
  50. }
  51. private:
  52. std::vector<binder<T>> members;
  53. };
  54. } }