json_direct_get_binder.hpp 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. //
  2. // json_direct_tuple_binder.hpp
  3. // json
  4. //
  5. // Created by Sam Jaffe on 2/26/17.
  6. //
  7. #pragma once
  8. #include <tuple>
  9. namespace json { namespace binder {
  10. template <typename T, std::size_t I>
  11. class get_binder : public binder_impl<T> {
  12. public:
  13. using value_type = typename std::remove_reference<decltype(std::get<I>(std::declval<T>()))>::type;
  14. get_binder(binder<value_type> val_binder)
  15. : impl(std::move(val_binder)) {
  16. }
  17. get_binder(binder_impl<value_type> const & val_binder = value_binder<value_type>())
  18. : impl(val_binder) {
  19. }
  20. virtual binder_impl<T>* clone() const override { return new get_binder(*this); }
  21. virtual void parse(T& object, char const*& data, parser::options opts) const override {
  22. impl.parse(std::get<I>(object), data, opts);
  23. }
  24. virtual void write(T const& val, std::ostream & data) const override {
  25. impl.write(std::get<I>(val), data);
  26. }
  27. private:
  28. binder<value_type> impl;
  29. };
  30. #if __cpluscplus >= 201402L
  31. namespace detail {
  32. template <typename TupleOut, typename TupleIn, std::size_t... Indexes>
  33. tuple_binder<TupleOut> make_tuple_binder(TupleIn && binds, std::index_sequence<Indexes...>) {
  34. tuple_binder<TupleOut> binder;
  35. using swallow = int[];
  36. (void) swallow{ 0, (void(binder(get_binder<TupleOut, Indexes>(std::get<Indexes>(binds)))), 0)... };
  37. return binder;
  38. }
  39. template <typename TupleOut, typename T, std::size_t... Indexes>
  40. tuple_binder<TupleOut> make_array_binder(binder<T> && binds, std::index_sequence<Indexes...>) {
  41. tuple_binder<TupleOut> binder;
  42. using swallow = int[];
  43. (void) swallow{ 0, (void(binder(get_binder<TupleOut, Indexes>(binds))), 0)... };
  44. return binder;
  45. }
  46. }
  47. template <typename... Ts>
  48. tuple_binder<std::tuple<Ts...>> make_tuple_binder(binder<Ts> &&... binds) {
  49. return detail::make_tuple_binder<std::tuple<Ts...>>(std::make_tuple(binds...), std::make_index_sequence<sizeof...(Ts)>());
  50. }
  51. template <typename... Ts>
  52. tuple_binder<std::tuple<Ts...>> make_tuple_binder(binder_impl<Ts> &&... binds) {
  53. return detail::make_tuple_binder<std::tuple<Ts...>>(std::make_tuple(binder<Ts>(binds)...), std::make_index_sequence<sizeof...(Ts)>());
  54. }
  55. template <typename... Ts>
  56. tuple_binder<std::tuple<Ts...>> make_default_tuple_binder() {
  57. return detail::make_tuple_binder<std::tuple<Ts...>>(std::make_tuple(binder<Ts>(value_binder<Ts>())...), std::make_index_sequence<sizeof...(Ts)>());
  58. }
  59. template <typename T, std::size_t N>
  60. tuple_binder<std::array<T, N>> make_array_binder(binder<T> && binds) {
  61. return detail::make_array_binder<std::array<T, N>>(binds, std::make_index_sequence<N>());
  62. }
  63. template <typename T, std::size_t N>
  64. tuple_binder<std::array<T, N>> make_array_binder(binder_impl<T> const & binds = value_binder<T>()) {
  65. return detail::make_array_binder<std::array<T, N>>(binder<T>(binds), std::make_index_sequence<N>());
  66. }
  67. #endif
  68. } }