Skip to content

kdbindings/make_node.h

Namespaces

Name
KDBindings
The main namespace of the KDBindings library.

Source code

 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-2022 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_<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

Updated on 2022-04-12 at 00:03:56 +0000

Back to top