2026-04-06 00:20:51 -05:00

107 lines
2.7 KiB
C++

/*
This file is part of KDBindings.
SPDX-FileCopyrightText: 2021 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
Author: Sean Harmer <sean.harmer@kdab.com>
SPDX-License-Identifier: MIT
Contact KDAB at <info@kdab.com> for commercial licensing options.
*/
#pragma once
#include <kdbindings/node.h>
#include <type_traits>
namespace KDBindings {
namespace Private {
template<typename T>
struct bindable_value_type_ {
using type = T;
};
template<typename T>
struct bindable_value_type_<Property<T>> {
using type = T;
};
template<typename T>
struct bindable_value_type_<const Property<T>> {
using type = T;
};
template<typename T>
struct bindable_value_type_<NodeInterface<T>> {
using type = T;
};
template<typename T>
struct bindable_value_type_<Node<T>> {
using type = T;
};
template<typename T>
struct bindable_value_type : bindable_value_type_<std::decay_t<T>> {
};
template<typename T>
using bindable_value_type_t = typename bindable_value_type<T>::type;
// Find the type of a Node wrapping an operator and arguments
template<typename Operator, typename... Ts>
using operator_node_result =
std::decay<
std::invoke_result_t<
std::decay_t<Operator>,
bindable_value_type_t<Ts>...>>;
template<typename Operator, typename... Ts>
using operator_node_result_t = typename operator_node_result<Operator, Ts...>::type;
// Node creation helpers
template<typename T>
inline Node<std::decay_t<T>> makeNode(T &&value)
{
return Node<std::decay_t<T>>(std::make_unique<ConstantNode<std::decay_t<T>>>(std::move(value)));
}
template<typename T>
inline Node<T> makeNode(Property<T> &property)
{
return Node<T>(std::make_unique<PropertyNode<T>>(property));
}
template<typename T>
inline Node<T> makeNode(const Property<T> &property)
{
return Node<T>(std::make_unique<PropertyNode<T>>(property));
}
template<typename T>
inline Node<T> makeNode(Node<T> &&node)
{
return std::move(node);
}
template<typename Operator, typename... Ts, typename = std::enable_if_t<sizeof...(Ts) >= 1>, typename ResultType = operator_node_result_t<Operator, Ts...>>
inline Node<ResultType> makeNode(Operator &&op, Ts &&...args)
{
return Node<ResultType>(std::make_unique<OperatorNode<ResultType, std::decay_t<Operator>, bindable_value_type_t<Ts>...>>(
std::forward<Operator>(op),
makeNode(std::forward<Ts>(args))...));
}
// Needed by function and operator helpers
template<typename T>
struct is_bindable : std::integral_constant<
bool,
is_property<T>::value || is_node<T>::value> {
};
} // namespace Private
} // namespace KDBindings