json_direct_vector_binder.hpp 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. //
  2. // json_direct_vector_binder.hpp
  3. // json
  4. //
  5. // Created by Sam Jaffe on 4/23/16.
  6. //
  7. #pragma once
  8. #include "json_binder.hpp"
  9. #include "json_direct_binder.hpp"
  10. #include <vector>
  11. #include <list>
  12. #include <set>
  13. namespace json { namespace binder {
  14. template <typename T, typename V, typename C>
  15. class non_associative_binder : public binder_impl<T> {
  16. public:
  17. non_associative_binder(C T::*p) : ptr(p), impl(value_binder<V>()) {}
  18. non_associative_binder(C T::*p, binder<V> const & i) : ptr(p), impl(i) {}
  19. virtual binder_impl<T>* clone() const override {
  20. return new non_associative_binder(*this);
  21. }
  22. virtual void parse(T& val, char const*& data,
  23. parser::options opts) const override {
  24. const char ch = json::helper::get_next_element(data);
  25. if (ch != '[') { throw not_an_array_exception(val); }
  26. ++data;
  27. V to_make;
  28. C & vec = val.*ptr;
  29. while (*data && *data != ']') {
  30. impl.parse(to_make, data, opts);
  31. vec.emplace_back(to_make);
  32. json::helper::advance_to_boundary(']', data);
  33. }
  34. if (*data) ++data;
  35. else throw unterminated_json_array();
  36. }
  37. virtual void write(T const& val, std::ostream & data) const override {
  38. data << '[';
  39. std::vector<V> const & vec = val.*ptr;
  40. auto it = vec.begin(), end = vec.end();
  41. if (it != end) {
  42. impl.write(*it, data);
  43. for (++it; it != end; ++it) {
  44. data << ",";
  45. impl.write(*it, data);
  46. }
  47. }
  48. data << ']';
  49. }
  50. private:
  51. std::vector<V> T::*ptr;
  52. binder<V> impl;
  53. };
  54. #define NON_ASSOCIATIVE_DIRECT_BINDER( C ) \
  55. template <typename T, typename V, typename... O> \
  56. class direct_binder<T, C<V, O...> > : \
  57. public non_associative_binder<T, V, C<V, O...>> { \
  58. public: \
  59. using non_associative_binder<T, V, C<V, O...>>::non_associative_binder; \
  60. }
  61. NON_ASSOCIATIVE_DIRECT_BINDER( std::vector );
  62. NON_ASSOCIATIVE_DIRECT_BINDER( std::list );
  63. NON_ASSOCIATIVE_DIRECT_BINDER( std::set );
  64. // NON_ASSOCIATIVE_DIRECT_BINDER( std::unordered_set );
  65. } }