| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- //
- // json_direct_tuple_binder.hpp
- // json
- //
- // Created by Sam Jaffe on 2/26/17.
- //
- #pragma once
- #include <tuple>
- namespace json { namespace binder {
- template <typename T, std::size_t I>
- class get_binder : public binder_impl<T> {
- public:
- using value_type = typename std::remove_reference<decltype(std::get<I>(std::declval<T>()))>::type;
-
- get_binder(binder<value_type> val_binder)
- : impl(std::move(val_binder)) {
-
- }
-
- get_binder(binder_impl<value_type> const & val_binder = value_binder<value_type>())
- : impl(val_binder) {
-
- }
-
- virtual binder_impl<T>* clone() const override { return new get_binder(*this); }
-
- virtual void parse(T& object, char const*& data, parser::options opts) const override {
- impl.parse(std::get<I>(object), data, opts);
- }
-
- virtual void write(T const& val, std::ostream & data) const override {
- impl.write(std::get<I>(val), data);
- }
- private:
- binder<value_type> impl;
- };
-
- #if __cpluscplus >= 201402L
- namespace detail {
- template <typename TupleOut, typename TupleIn, std::size_t... Indexes>
- tuple_binder<TupleOut> make_tuple_binder(TupleIn && binds, std::index_sequence<Indexes...>) {
- tuple_binder<TupleOut> binder;
- using swallow = int[];
- (void) swallow{ 0, (void(binder(get_binder<TupleOut, Indexes>(std::get<Indexes>(binds)))), 0)... };
- return binder;
- }
-
- template <typename TupleOut, typename T, std::size_t... Indexes>
- tuple_binder<TupleOut> make_array_binder(binder<T> && binds, std::index_sequence<Indexes...>) {
- tuple_binder<TupleOut> binder;
- using swallow = int[];
- (void) swallow{ 0, (void(binder(get_binder<TupleOut, Indexes>(binds))), 0)... };
- return binder;
- }
- }
-
- template <typename... Ts>
- tuple_binder<std::tuple<Ts...>> make_tuple_binder(binder<Ts> &&... binds) {
- return detail::make_tuple_binder<std::tuple<Ts...>>(std::make_tuple(binds...), std::make_index_sequence<sizeof...(Ts)>());
- }
- template <typename... Ts>
- tuple_binder<std::tuple<Ts...>> make_tuple_binder(binder_impl<Ts> &&... binds) {
- return detail::make_tuple_binder<std::tuple<Ts...>>(std::make_tuple(binder<Ts>(binds)...), std::make_index_sequence<sizeof...(Ts)>());
- }
-
- template <typename... Ts>
- tuple_binder<std::tuple<Ts...>> make_default_tuple_binder() {
- return detail::make_tuple_binder<std::tuple<Ts...>>(std::make_tuple(binder<Ts>(value_binder<Ts>())...), std::make_index_sequence<sizeof...(Ts)>());
- }
-
- template <typename T, std::size_t N>
- tuple_binder<std::array<T, N>> make_array_binder(binder<T> && binds) {
- return detail::make_array_binder<std::array<T, N>>(binds, std::make_index_sequence<N>());
- }
-
- template <typename T, std::size_t N>
- tuple_binder<std::array<T, N>> make_array_binder(binder_impl<T> const & binds = value_binder<T>()) {
- return detail::make_array_binder<std::array<T, N>>(binder<T>(binds), std::make_index_sequence<N>());
- }
- #endif
- } }
|