|
|
@@ -19,33 +19,33 @@ namespace json { namespace binder {
|
|
|
class get_binder : public binder_impl<T> {
|
|
|
// Maybe a reference type
|
|
|
using ith_type = decltype(std::get<I>(std::declval<T>()));
|
|
|
+
|
|
|
public:
|
|
|
using value_type = typename std::remove_reference<ith_type>::type;
|
|
|
-
|
|
|
+
|
|
|
get_binder() : impl(value_binder<value_type>()) {}
|
|
|
-
|
|
|
- get_binder(binder<value_type> val_binder)
|
|
|
- : impl(std::move(val_binder)) {}
|
|
|
-
|
|
|
- get_binder(binder_impl<value_type> const & val_binder)
|
|
|
- : impl(val_binder) {}
|
|
|
-
|
|
|
- virtual binder_impl<T>* clone() const override {
|
|
|
+
|
|
|
+ get_binder(binder<value_type> val_binder) : impl(std::move(val_binder)) {}
|
|
|
+
|
|
|
+ get_binder(binder_impl<value_type> const & val_binder) : impl(val_binder) {}
|
|
|
+
|
|
|
+ virtual binder_impl<T> * clone() const override {
|
|
|
return new get_binder(*this);
|
|
|
}
|
|
|
-
|
|
|
- virtual void parse(T& object, char const*& data,
|
|
|
+
|
|
|
+ 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 {
|
|
|
+
|
|
|
+ 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>
|
|
|
@@ -53,141 +53,134 @@ namespace json { namespace binder {
|
|
|
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)...
|
|
|
- };
|
|
|
+ (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)...
|
|
|
- };
|
|
|
+ (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)>());
|
|
|
+ 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)>());
|
|
|
+ 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)>());
|
|
|
+ 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>());
|
|
|
+ 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>());
|
|
|
+ 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>());
|
|
|
}
|
|
|
#else
|
|
|
namespace detail {
|
|
|
template <std::size_t> struct tuple_binder_helper;
|
|
|
-
|
|
|
- template <>
|
|
|
- struct tuple_binder_helper<0> {
|
|
|
+
|
|
|
+ template <> struct tuple_binder_helper<0> {
|
|
|
template <typename BindOut>
|
|
|
tuple_binder<BindOut> & operator()(tuple_binder<BindOut> & bind) const {
|
|
|
return bind;
|
|
|
}
|
|
|
};
|
|
|
-
|
|
|
- template <std::size_t N>
|
|
|
- struct tuple_binder_helper {
|
|
|
+
|
|
|
+ template <std::size_t N> struct tuple_binder_helper {
|
|
|
template <typename BindOut, typename BindIn, typename... Ts>
|
|
|
tuple_binder<BindOut> & operator()(tuple_binder<BindOut> & bind,
|
|
|
BindIn && ith,
|
|
|
Ts &&... binders) const {
|
|
|
- constexpr auto get_index = std::tuple_size<BindOut>::value-N;
|
|
|
+ constexpr auto get_index = std::tuple_size<BindOut>::value - N;
|
|
|
using get_binder_t = get_binder<BindOut, get_index>;
|
|
|
- return tuple_binder_helper<N-1>()
|
|
|
- (bind(get_binder_t(std::forward<BindIn>(ith))),
|
|
|
- std::forward<Ts>(binders)...);
|
|
|
+ return tuple_binder_helper<N - 1>()(
|
|
|
+ bind(get_binder_t(std::forward<BindIn>(ith))),
|
|
|
+ std::forward<Ts>(binders)...);
|
|
|
}
|
|
|
};
|
|
|
-
|
|
|
+
|
|
|
template <std::size_t> struct array_binder_helper;
|
|
|
-
|
|
|
- template <>
|
|
|
- struct array_binder_helper<1> {
|
|
|
+
|
|
|
+ template <> struct array_binder_helper<1> {
|
|
|
template <typename BindOut, typename BindIn>
|
|
|
tuple_binder<BindOut> & operator()(tuple_binder<BindOut> & bind,
|
|
|
BindIn &&) const {
|
|
|
return bind;
|
|
|
}
|
|
|
};
|
|
|
-
|
|
|
- template <std::size_t N>
|
|
|
- struct array_binder_helper {
|
|
|
+
|
|
|
+ template <std::size_t N> struct array_binder_helper {
|
|
|
template <typename BindOut, typename BindIn>
|
|
|
tuple_binder<BindOut> & operator()(tuple_binder<BindOut> & bind,
|
|
|
BindIn && ith) const {
|
|
|
- return array_binder_helper<N-1>()(bind(get_binder<BindOut, N-1>(ith)),
|
|
|
- std::forward<BindIn>(ith));
|
|
|
+ return array_binder_helper<N - 1>()(
|
|
|
+ bind(get_binder<BindOut, N - 1>(ith)), std::forward<BindIn>(ith));
|
|
|
}
|
|
|
};
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
template <typename... Ts>
|
|
|
tuple_binder<std::tuple<Ts...>> make_tuple_binder(binder<Ts> &&... binds) {
|
|
|
tuple_binder<std::tuple<Ts...>> binder;
|
|
|
- return detail::tuple_binder_helper<sizeof...(Ts)>()
|
|
|
- (binder, std::forward<Ts>(binds)...);
|
|
|
+ return detail::tuple_binder_helper<sizeof...(Ts)>()(
|
|
|
+ binder, std::forward<Ts>(binds)...);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
template <typename... Ts>
|
|
|
- tuple_binder<std::tuple<Ts...>> make_tuple_binder(binder_impl<Ts> &&... binds) {
|
|
|
+ tuple_binder<std::tuple<Ts...>>
|
|
|
+ make_tuple_binder(binder_impl<Ts> &&... binds) {
|
|
|
tuple_binder<std::tuple<Ts...>> binder;
|
|
|
- return detail::tuple_binder_helper<sizeof...(Ts)>()
|
|
|
- (binder, json::binder::binder<Ts>(binds)...);
|
|
|
+ return detail::tuple_binder_helper<sizeof...(Ts)>()(
|
|
|
+ binder, json::binder::binder<Ts>(binds)...);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
template <typename... Ts>
|
|
|
tuple_binder<std::tuple<Ts...>> make_default_tuple_binder() {
|
|
|
tuple_binder<std::tuple<Ts...>> binder;
|
|
|
- return detail::tuple_binder_helper<sizeof...(Ts)>()
|
|
|
- (binder, json::binder::binder<Ts>(value_binder<Ts>())...);
|
|
|
+ return detail::tuple_binder_helper<sizeof...(Ts)>()(
|
|
|
+ binder, json::binder::binder<Ts>(value_binder<Ts>())...);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
template <typename T, std::size_t N>
|
|
|
tuple_binder<std::array<T, N>> make_array_binder(binder<T> && binds) {
|
|
|
tuple_binder<std::array<T, N>> binder;
|
|
|
return detail::array_binder_helper<N>(binder, binds);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
template <typename T, std::size_t N>
|
|
|
- tuple_binder<std::array<T, N>> make_array_binder(binder_impl<T> const & binds
|
|
|
- = value_binder<T>()) {
|
|
|
+ tuple_binder<std::array<T, N>>
|
|
|
+ make_array_binder(binder_impl<T> const & binds = value_binder<T>()) {
|
|
|
tuple_binder<std::array<T, N>> binder;
|
|
|
return detail::array_binder_helper<N>(binder,
|
|
|
json::binder::binder<T>(binds));
|
|
|
}
|
|
|
#endif
|
|
|
-} }
|
|
|
+}}
|