File indexing completed on 2024-06-23 05:27:09

0001 /*
0002     SPDX-FileCopyrightText: 2018 Ivan Čukić <ivan.cukic(at)kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 
0007 #ifndef VOY_NODE_TRAITS_H
0008 #define VOY_NODE_TRAITS_H
0009 
0010 // STL
0011 #include <utility>
0012 
0013 #include "node_tags.h"
0014 
0015 #include "../traits.h"
0016 #include "../utils.h"
0017 #include "../basic/sink.h"
0018 
0019 namespace voy::dsl::node_traits {
0020 
0021 using namespace voy::traits;
0022 
0023 // Returns the category of the node. It can also be used to detect whether
0024 // a class contains the node category specification
0025 template <typename Node>
0026 using node_category = typename remove_cvref_t<Node>::node_category;
0027 
0028 
0029 // Used to detect whther the class contains a with_continuation function
0030 // for rvalues
0031 template <typename Node>
0032 using with_continuation_memfn = decltype(
0033         std::declval<Node&&>().with_continuation(voy::sink<void>{}));
0034 
0035 template <typename Node>
0036 voy_concept has_with_continuation = is_detected_v<with_continuation_memfn, Node>;
0037 
0038 
0039 // Returns whether the node has the specified tag or not
0040 template <typename Tag, typename Node>
0041 voy_concept is_tagged_with = std::is_same_v<Tag, node_category<Node>>;
0042 
0043 
0044 // The meta-function to check whether a class is a node is easier to implement
0045 // using the constexpr-if because of the branching.
0046 namespace detail {
0047     template < typename Node
0048              , typename DetectedCategory = detected_t<node_category, Node>
0049              >
0050     voy_concept is_node()
0051     {
0052         if constexpr (!is_detected_v<node_category, Node>) {
0053             // voy_fail(Node, "No category specified for the node");
0054             return false;
0055 
0056         } else if constexpr (std::is_same_v<void, DetectedCategory>) {
0057             // voy_fail(Node, "Category is void, which means we already have a complete graph path");
0058             return false;
0059 
0060         } else {
0061             return true;
0062         }
0063     }
0064 }
0065 
0066 // Wrapper for detail::is_node to make it look like a normal meta-function
0067 template <typename Node>
0068 voy_concept is_node = detail::is_node<Node>();
0069 
0070 
0071 // Checks whether the node is a source node
0072 template <typename Node>
0073 voy_concept is_source = is_tagged_with<source_node_tag, Node>;
0074 
0075 
0076 // Checks whether the node is a source node
0077 template <typename Node>
0078 voy_concept is_sink = is_tagged_with<sink_node_tag, Node>;
0079 
0080 
0081 // To be used with the detection idiom to check whether a type is
0082 // a connection_expr or a normal node
0083 template <typename Graph>
0084 using connection_expr_tag_definition = typename Graph::connection_expr_tag;
0085 
0086 template <typename Node>
0087 voy_concept is_connection_expr =
0088     is_detected_v<connection_expr_tag_definition, Node>;
0089 
0090 
0091 
0092 } // namespace voy::dsl::node_traits
0093 
0094 #endif // include guard
0095