| 1 | /*
 | 
| 2 |  * Souffle - A Datalog Compiler
 | 
| 3 |  * Copyright (c) 2021, The Souffle Developers. All rights reserved
 | 
| 4 |  * Licensed under the Universal Permissive License v 1.0 as shown at:
 | 
| 5 |  * - https://opensource.org/licenses/UPL
 | 
| 6 |  * - <souffle root>/licenses/SOUFFLE-UPL.txt
 | 
| 7 |  */
 | 
| 8 | 
 | 
| 9 | /************************************************************************
 | 
| 10 |  *
 | 
| 11 |  * @file VisitorFwd.h
 | 
| 12 |  *
 | 
| 13 |  * Defines the bare minimum for declaring a visitable root type.
 | 
| 14 |  * Separate header to avoid dragging in everything used by `Visitor.h`.
 | 
| 15 |  *
 | 
| 16 |  ***********************************************************************/
 | 
| 17 | 
 | 
| 18 | #pragma once
 | 
| 19 | 
 | 
| 20 | #include "souffle/utility/Types.h"
 | 
| 21 | #include <type_traits>
 | 
| 22 | 
 | 
| 23 | #define SOUFFLE_DECLARE_VISITABLE_ROOT_TYPE(ty)                                    \
 | 
| 24 |     template <typename A>                                                          \
 | 
| 25 |     struct souffle::detail::VisitRootType_t<A,                                     \
 | 
| 26 |             std::enable_if_t<std::is_base_of_v<ty, ::souffle::remove_cvref_t<A>>>> \
 | 
| 27 |             : souffle::detail::VisitRootType_t<A, ty> {};
 | 
| 28 | 
 | 
| 29 | namespace souffle::detail {
 | 
| 30 | template <typename A, typename R = void>
 | 
| 31 | struct VisitRootType_t {
 | 
| 32 |     using type = R;
 | 
| 33 | };
 | 
| 34 | 
 | 
| 35 | template <typename A>
 | 
| 36 | using visit_root_type_or_void = typename VisitRootType_t<remove_cvref_t<A>>::type;
 | 
| 37 | 
 | 
| 38 | template <typename A>
 | 
| 39 | constexpr bool is_visitable_node = !std::is_same_v<void, visit_root_type_or_void<A>>;
 | 
| 40 | 
 | 
| 41 | template <typename A>
 | 
| 42 | using visit_root_type = std::enable_if_t<is_visitable_node<A>, visit_root_type_or_void<A>>;
 | 
| 43 | }  // namespace souffle::detail
 |