| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- // Copyright (C) 2020 The Qt Company Ltd.
- // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
- #pragma once
- #include <functional>
- #include <tuple>
- // C++14 compatible apply implementation
- namespace detail {
- template<class F, class Tuple, std::size_t... I>
- constexpr auto apply_impl(F&& f, Tuple&& t, std::index_sequence<I...>)
- -> decltype(std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))...))
- {
- return std::forward<F>(f)(std::get<I>(std::forward<Tuple>(t))...);
- }
- }
- template<class F, class Tuple>
- constexpr auto apply(F&& f, Tuple&& t)
- -> decltype(detail::apply_impl(std::forward<F>(f), std::forward<Tuple>(t),
- std::make_index_sequence<std::tuple_size<std::decay_t<Tuple>>::value>{}))
- {
- return detail::apply_impl(std::forward<F>(f), std::forward<Tuple>(t),
- std::make_index_sequence<std::tuple_size<std::decay_t<Tuple>>::value>{});
- }
- namespace Building {
- class NestId {};
- template <typename Id, typename Arg>
- class IdAndArg
- {
- public:
- IdAndArg(Id, const Arg &arg) : arg(arg) {}
- const Arg arg; // FIXME: Could be const &, but this would currently break bindTo().
- };
- // The main dispatcher
- template<typename X, typename Id, typename P>
- void doit(X x, Id id, P p);
- template <typename X> class BuilderItem
- {
- public:
- // Property setter
- template <typename Id, typename Arg>
- BuilderItem(IdAndArg<Id, Arg> && idarg)
- : apply([&idarg](X *x) { doit(x, Id{}, idarg.arg); })
- {}
- // Nested child object
- template <typename Inner>
- BuilderItem(Inner && p)
- : apply([&p](X *x) { doit(x, NestId{}, std::forward<Inner>(p)); })
- {}
- const std::function<void(X *)> apply;
- };
- #define QTC_DEFINE_BUILDER_SETTER(name, setter) \
- class name##_TAG {}; \
- template <typename ...Args> \
- inline auto name(Args &&...args) { \
- return Building::IdAndArg{name##_TAG{}, std::tuple<Args...>{std::forward<Args>(args)...}}; \
- } \
- template <typename L, typename ...Args> \
- inline void doit(L *x, name##_TAG, const std::tuple<Args...> &arg) { \
- apply(&L::setter, std::tuple_cat(std::make_tuple(x), arg)); \
- }
- } // Building
|