-
Notifications
You must be signed in to change notification settings - Fork 167
/
make_node.h
95 lines (73 loc) · 2.45 KB
/
make_node.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/*
This file is part of KDBindings.
SPDX-FileCopyrightText: 2021-2023 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
Author: Sean Harmer <[email protected]>
SPDX-License-Identifier: MIT
Contact KDAB at <[email protected]> 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_<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(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