Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions llvm/include/llvm/ExecutionEngine/Orc/CallableTraitsHelper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//===- CallableTraitsHelper.h - Callable arg/ret type extractor -*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// CallableTraitsHelper API.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_EXECUTIONENGINE_ORC_CALLABLETRAITSHELPER_H
#define LLVM_EXECUTIONENGINE_ORC_CALLABLETRAITSHELPER_H

#include <tuple>
#include <type_traits>

namespace llvm::orc {

/// CallableTraitsHelper takes an implementation class template Impl and some
/// callable type C and passes the return and argument types of C to the Impl
/// class template.
///
/// This can be used to simplify the implementation of classes that need to
/// operate on callable types.
template <template <typename...> typename ImplT, typename C>
struct CallableTraitsHelper
: public CallableTraitsHelper<
ImplT,
decltype(&std::remove_cv_t<std::remove_reference_t<C>>::operator())> {
};

template <template <typename...> typename ImplT, typename RetT,
typename... ArgTs>
struct CallableTraitsHelper<ImplT, RetT(ArgTs...)>
: public ImplT<RetT, ArgTs...> {};

template <template <typename...> typename ImplT, typename RetT,
typename... ArgTs>
struct CallableTraitsHelper<ImplT, RetT (*)(ArgTs...)>
: public CallableTraitsHelper<ImplT, RetT(ArgTs...)> {};

template <template <typename...> typename ImplT, typename RetT,
typename... ArgTs>
struct CallableTraitsHelper<ImplT, RetT (&)(ArgTs...)>
: public CallableTraitsHelper<ImplT, RetT(ArgTs...)> {};

template <template <typename...> typename ImplT, typename ClassT, typename RetT,
typename... ArgTs>
struct CallableTraitsHelper<ImplT, RetT (ClassT::*)(ArgTs...)>
: public CallableTraitsHelper<ImplT, RetT(ArgTs...)> {};

template <template <typename...> typename ImplT, typename ClassT, typename RetT,
typename... ArgTs>
struct CallableTraitsHelper<ImplT, RetT (ClassT::*)(ArgTs...) const>
: public CallableTraitsHelper<ImplT, RetT(ArgTs...)> {};

namespace detail {
template <typename RetT, typename... ArgTs> struct CallableArgInfoImpl {
using ReturnType = RetT;
using ArgsTupleType = std::tuple<ArgTs...>;
};
} // namespace detail

/// CallableArgInfo provides typedefs for the return type and argument types
/// (as a tuple) of the given callable type.
template <typename Callable>
struct CallableArgInfo
: public CallableTraitsHelper<detail::CallableArgInfoImpl, Callable> {};

} // namespace llvm::orc

#endif // LLVM_EXECUTIONENGINE_ORC_CALLABLETRAITSHELPER_H
1 change: 1 addition & 0 deletions llvm/unittests/ExecutionEngine/Orc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ set(LLVM_LINK_COMPONENTS
)

add_llvm_unittest(OrcJITTests
CallableTraitsHelperTest.cpp
CoreAPIsTest.cpp
ExecutorAddressTest.cpp
ExecutionSessionWrapperFunctionCallsTest.cpp
Expand Down
70 changes: 70 additions & 0 deletions llvm/unittests/ExecutionEngine/Orc/CallableTraitsHelperTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
//===- CallableTraitsHelperTest.cpp ---------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Tests for llvm::orc::CallableTraitsHelper APIs.
//
// NOTE: All tests in this file are testing compile-time functionality, so the
// tests at runtime all end up being noops. That's fine -- those are
// cheap.
//===----------------------------------------------------------------------===//

#include "llvm/ExecutionEngine/Orc/CallableTraitsHelper.h"
#include "gtest/gtest.h"

using namespace llvm;
using namespace llvm::orc;

static void freeVoidVoid() {}

TEST(CallableTraitsHelperTest, FreeVoidVoid) {
(void)freeVoidVoid;
typedef CallableArgInfo<decltype(freeVoidVoid)> CAI;
static_assert(std::is_void_v<CAI::ReturnType>);
static_assert(std::is_same_v<CAI::ArgsTupleType, std::tuple<>>);
}

static int freeBinaryOp(int, float) { return 0; }

TEST(CallableTraitsHelperTest, FreeBinaryOp) {
(void)freeBinaryOp;
typedef CallableArgInfo<decltype(freeBinaryOp)> CAI;
static_assert(std::is_same_v<CAI::ReturnType, int>);
static_assert(std::is_same_v<CAI::ArgsTupleType, std::tuple<int, float>>);
}

TEST(CallableTraitsHelperTest, VoidVoidObj) {
auto VoidVoid = []() {};
typedef CallableArgInfo<decltype(VoidVoid)> CAI;
static_assert(std::is_void_v<CAI::ReturnType>);
static_assert(std::is_same_v<CAI::ArgsTupleType, std::tuple<>>);
}

TEST(CallableTraitsHelperTest, BinaryOpObj) {
auto BinaryOp = [](int X, float Y) -> int { return X + Y; };
typedef CallableArgInfo<decltype(BinaryOp)> CAI;
static_assert(std::is_same_v<CAI::ReturnType, int>);
static_assert(std::is_same_v<CAI::ArgsTupleType, std::tuple<int, float>>);
}

TEST(CallableTraitsHelperTest, PreservesLValueRef) {
auto RefOp = [](int &) {};
typedef CallableArgInfo<decltype(RefOp)> CAI;
static_assert(std::is_same_v<CAI::ArgsTupleType, std::tuple<int &>>);
}

TEST(CallableTraitsHelperTest, PreservesLValueRefConstness) {
auto RefOp = [](const int &) {};
typedef CallableArgInfo<decltype(RefOp)> CAI;
static_assert(std::is_same_v<CAI::ArgsTupleType, std::tuple<const int &>>);
}

TEST(CallableTraitsHelperTest, PreservesRValueRef) {
auto RefOp = [](int &&) {};
typedef CallableArgInfo<decltype(RefOp)> CAI;
static_assert(std::is_same_v<CAI::ArgsTupleType, std::tuple<int &&>>);
}