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