json_tuple_binder.hpp 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  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, parser::options opts) const override {
  18. const char ch = json::helper::get_next_element(data);
  19. if (ch == '[') {
  20. parse_tuple(object, ++data, opts);
  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::ostream & data) const override {
  26. data << '[';
  27. typename std::vector<binder<T>>::const_iterator it = members.begin(),
  28. end = members.end();
  29. if (it != end) {
  30. it->write(val, data);
  31. for (++it; it != end; ++it) {
  32. data << ',';
  33. it->write(val, data);
  34. }
  35. }
  36. data << ']';
  37. }
  38. void parse_tuple(T& object, char const*& data, parser::options opts) const {
  39. auto it = members.begin();
  40. while (*data && *data != ']' && it != members.end()) {
  41. it->parse(object, data, opts);
  42. json::helper::advance_to_boundary(']', data);
  43. ++it;
  44. }
  45. if (it != members.end()) {
  46. throw json::malformed_json_exception("Failed to parse every member of tuple");
  47. }
  48. if (*data != ']') throw json::malformed_json_exception("Parsed every tuple element, but did not reach end");
  49. else if (*data) ++data;
  50. else throw json::unterminated_json_exception("Reached end of parse string without finding array end");
  51. }
  52. template <typename E>
  53. tuple_binder& operator()(E T::*p) {
  54. return operator()(binder<T>(new direct_binder<T, E>(p)));
  55. }
  56. private:
  57. std::vector<binder<T>> members;
  58. };
  59. } }