json_direct_vector_binder.hpp 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. //
  2. // json_direct_vector_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, typename V, typename C>
  10. class non_associative_binder : public binder_impl<T> {
  11. public:
  12. non_associative_binder(C T::*p) : ptr(p), impl(value_binder<V>()) {}
  13. non_associative_binder(C T::*p, binder<V> const & i) : ptr(p), impl(i) {}
  14. virtual binder_impl<T>* clone() const override { return new non_associative_binder(*this); }
  15. virtual void parse(T& val, char const*& data, parser::options opts) const override {
  16. const char ch = json::helper::get_next_element(data);
  17. if (ch != '[') {
  18. throw json::malformed_json_exception("Expected an array type");
  19. }
  20. ++data;
  21. V to_make;
  22. C & vec = val.*ptr;
  23. while (*data && *data != ']') {
  24. impl.parse(to_make, data, opts);
  25. vec.emplace_back(to_make);
  26. json::helper::advance_to_boundary(']', data);
  27. }
  28. if (*data) ++data;
  29. else throw json::unterminated_json_exception("Reached end of parse string without finding array end");
  30. }
  31. virtual void write(T const& val, std::ostream & data) const override {
  32. data << '[';
  33. std::vector<V> const & vec = val.*ptr;
  34. auto it = vec.begin(), end = vec.end();
  35. if (it != end) {
  36. impl.write(*it, data);
  37. for (++it; it != end; ++it) {
  38. data << ",";
  39. impl.write(*it, data);
  40. }
  41. }
  42. data << ']';
  43. }
  44. private:
  45. std::vector<V> T::*ptr;
  46. binder<V> impl;
  47. };
  48. #define NON_ASSOCIATIVE_DIRECT_BINDER( C ) \
  49. template <typename T, typename V, typename... O> \
  50. class direct_binder<T, C<V, O...> > : \
  51. public non_associative_binder<T, V, C<V, O...>> { \
  52. public: \
  53. using non_associative_binder<T, V, C<V, O...>>::non_associative_binder; \
  54. }
  55. NON_ASSOCIATIVE_DIRECT_BINDER( std::vector );
  56. NON_ASSOCIATIVE_DIRECT_BINDER( std::list );
  57. NON_ASSOCIATIVE_DIRECT_BINDER( std::set );
  58. // NON_ASSOCIATIVE_DIRECT_BINDER( std::unordered_set );
  59. } }