Select Git revision
MeshSmoother.cpp
PugsFunctionAdapter.hpp 13.07 KiB
#ifndef PUGS_FUNCTION_ADAPTER_HPP
#define PUGS_FUNCTION_ADAPTER_HPP
#include <language/ast/ASTNode.hpp>
#include <language/node_processor/ExecutionPolicy.hpp>
#include <language/utils/ASTNodeDataType.hpp>
#include <language/utils/ASTNodeDataTypeTraits.hpp>
#include <language/utils/SymbolTable.hpp>
#include <utils/Array.hpp>
#include <utils/Exceptions.hpp>
#include <utils/PugsMacros.hpp>
#include <Kokkos_Core.hpp>
#include <array>
template <typename T>
class PugsFunctionAdapter;
template <typename OutputType, typename... InputType>
class PugsFunctionAdapter<OutputType(InputType...)>
{
protected:
using InputTuple = std::tuple<std::decay_t<InputType>...>;
constexpr static size_t NArgs = std::tuple_size_v<InputTuple>;
private:
template <typename T, typename... Args>
PUGS_INLINE static void
_convertArgs(ExecutionPolicy::Context& context, size_t i_context, const T& t, Args&&... args)
{
context[i_context++] = t;
if constexpr (sizeof...(Args) > 0) {
_convertArgs(context, i_context, std::forward<Args>(args)...);
}
}
template <size_t I>
[[nodiscard]] PUGS_INLINE static bool
_checkValidArgumentDataType(const ASTNode& arg_expression) noexcept(NO_ASSERT)
{
using Arg = std::tuple_element_t<I, InputTuple>;
constexpr const ASTNodeDataType& expected_input_data_type = ast_node_data_type_from<Arg>;
Assert(arg_expression.m_data_type == ASTNodeDataType::typename_t);
const ASTNodeDataType& arg_data_type = arg_expression.m_data_type.contentType();
return isNaturalConversion(expected_input_data_type, arg_data_type);
}
template <size_t... I>
[[nodiscard]] PUGS_INLINE static bool
_checkAllInputDataType(const ASTNode& input_expression, std::index_sequence<I...>)
{
Assert(NArgs == input_expression.children.size());
return (_checkValidArgumentDataType<I>(*input_expression.children[I]) and ...);
}
[[nodiscard]] PUGS_INLINE static bool
_checkValidInputDomain(const ASTNode& input_domain_expression) noexcept
{
if constexpr (NArgs == 1) {
return _checkValidArgumentDataType<0>(input_domain_expression);
} else {
if ((input_domain_expression.m_data_type.contentType() != ASTNodeDataType::list_t) or
(input_domain_expression.children.size() != NArgs)) {
return false;
}
using IndexSequence = std::make_index_sequence<NArgs>;