| 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 NodeMapperFwd.h
 | 
| 12 |  *
 | 
| 13 |  * Trivial forward decls for `NodeMapper.h`
 | 
| 14 |  *
 | 
| 15 |  ***********************************************************************/
 | 
| 16 | 
 | 
| 17 | #pragma once
 | 
| 18 | 
 | 
| 19 | #include "souffle/utility/DynamicCasting.h"
 | 
| 20 | #include "souffle/utility/Types.h"
 | 
| 21 | #include "souffle/utility/VisitorFwd.h"
 | 
| 22 | #include <type_traits>
 | 
| 23 | #include <utility>
 | 
| 24 | 
 | 
| 25 | namespace souffle {
 | 
| 26 | namespace detail {
 | 
| 27 | /**
 | 
| 28 |  * An abstract class for manipulating AST Nodes by substitution
 | 
| 29 |  */
 | 
| 30 | template <typename Node>
 | 
| 31 | struct NodeMapper {
 | 
| 32 |     static_assert(is_visitable_node<Node>);
 | 
| 33 | 
 | 
| 34 |     virtual ~NodeMapper() = default;
 | 
| 35 | 
 | 
| 36 |     /**
 | 
| 37 |      * Abstract replacement method for a node.
 | 
| 38 |      *
 | 
| 39 |      * If the given nodes is to be replaced, the handed in node
 | 
| 40 |      * will be destroyed by the mapper and the returned node
 | 
| 41 |      * will become owned by the caller.
 | 
| 42 |      */
 | 
| 43 |     virtual Own<Node> operator()(Own<Node> node) const = 0;
 | 
| 44 | 
 | 
| 45 |     /**
 | 
| 46 |      * Wrapper for any subclass of the AST node hierarchy performing type casts.
 | 
| 47 |      */
 | 
| 48 |     template <typename T>
 | 
| 49 |     Own<T> operator()(Own<T> node) const {
 | 
| 50 |         return UNSAFE_cast<T>((*this)(Own<Node>(std::move(node))));
 | 
| 51 |     }
 | 
| 52 | };
 | 
| 53 | }  // namespace detail
 | 
| 54 | 
 | 
| 55 | template <typename R, typename Node>
 | 
| 56 | void mapAll(R& range, detail::NodeMapper<Node> const& mapper) {
 | 
| 57 |     static_assert(std::is_assignable_v<Own<Node>, decltype(std::move(*std::begin(std::declval<R&>())))>,
 | 
| 58 |             "range/container element isn't a subtype of `Own<Node>`");
 | 
| 59 | 
 | 
| 60 |     // this one is small / common enough to define in fwd, save people from including the heavier weight stuff
 | 
| 61 |     for (auto& cur : range) {
 | 
| 62 |         cur = mapper(std::move(cur));
 | 
| 63 |     }
 | 
| 64 | }
 | 
| 65 | 
 | 
| 66 | }  // namespace souffle
 |