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
1 change: 1 addition & 0 deletions orc-rt/include/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ set(ORC_RT_HEADERS
orc-rt/RTTI.h
orc-rt/WrapperFunctionResult.h
orc-rt/SimplePackedSerialization.h
orc-rt/bind.h
orc-rt/bit.h
orc-rt/move_only_function.h
orc-rt/span.h
Expand Down
56 changes: 56 additions & 0 deletions orc-rt/include/orc-rt/bind.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//===---- bind.h - Substitute for future STL bind_front APIs ----*- 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
//
//===----------------------------------------------------------------------===//
//
// Substitute for STL bind* APIs that aren't available to the ORC runtime yet.
//
// TODO: Replace all uses once the respective APIs are available.
//
//===----------------------------------------------------------------------===//

#ifndef ORC_RT_BIND_H
#define ORC_RT_BIND_H

#include <tuple>
#include <type_traits>

namespace orc_rt {
namespace detail {

template <typename Fn, typename... BoundArgTs> class BoundFn {
private:
template <size_t... Is, typename... ArgTs>
auto callExpandingBound(std::index_sequence<Is...>, ArgTs &&...Args) {
return F(std::get<Is>(BoundArgs)..., std::move(Args)...);
}

public:
BoundFn(Fn &&F, BoundArgTs &&...BoundArgs)
: F(std::move(F)), BoundArgs(std::forward<BoundArgTs>(BoundArgs)...) {}

template <typename... ArgTs> auto operator()(ArgTs &&...Args) {
return callExpandingBound(std::index_sequence_for<BoundArgTs...>(),
std::forward<ArgTs>(Args)...);
}

private:
std::decay_t<Fn> F;
std::tuple<std::decay_t<BoundArgTs>...> BoundArgs;
};

} // namespace detail

template <typename Fn, typename... BoundArgTs>
detail::BoundFn<Fn, BoundArgTs...> bind_front(Fn &&F,
BoundArgTs &&...BoundArgs) {
return detail::BoundFn<Fn, BoundArgTs...>(
std::forward<Fn>(F), std::forward<BoundArgTs>(BoundArgs)...);
}

} // namespace orc_rt

#endif // ORC_RT_BIND_H
2 changes: 2 additions & 0 deletions orc-rt/unittests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ endfunction()

add_orc_rt_unittest(CoreTests
BitmaskEnumTest.cpp
CommonTestUtils.cpp
ErrorTest.cpp
ExecutorAddressTest.cpp
IntervalMapTest.cpp
Expand All @@ -21,6 +22,7 @@ add_orc_rt_unittest(CoreTests
RTTITest.cpp
SimplePackedSerializationTest.cpp
WrapperFunctionResultTest.cpp
bind-test.cpp
bit-test.cpp
move_only_function-test.cpp
span-test.cpp
Expand Down
20 changes: 20 additions & 0 deletions orc-rt/unittests/CommonTestUtils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//===- CommonTestUtils.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
//
//===----------------------------------------------------------------------===//
//
// Common test utilities.
//
//===----------------------------------------------------------------------===//

#include "CommonTestUtils.h"

size_t OpCounter::DefaultConstructions = 0;
size_t OpCounter::CopyConstructions = 0;
size_t OpCounter::CopyAssignments = 0;
size_t OpCounter::MoveConstructions = 0;
size_t OpCounter::MoveAssignments = 0;
size_t OpCounter::Destructions = 0;
60 changes: 60 additions & 0 deletions orc-rt/unittests/CommonTestUtils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//===- CommonTestUtils.h --------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#ifndef ORC_RT_UNITTEST_COMMONTESTUTILS_H
#define ORC_RT_UNITTEST_COMMONTESTUTILS_H

#include <cstddef>

class OpCounter {
public:
OpCounter() { ++DefaultConstructions; }
OpCounter(const OpCounter &Other) { ++CopyConstructions; }
OpCounter &operator=(const OpCounter &Other) {
++CopyAssignments;
return *this;
}
OpCounter(OpCounter &&Other) { ++MoveConstructions; }
OpCounter &operator=(OpCounter &&Other) {
++MoveAssignments;
return *this;
}
~OpCounter() { ++Destructions; }

static size_t defaultConstructions() { return DefaultConstructions; }
static size_t copyConstructions() { return CopyConstructions; }
static size_t copyAssignments() { return CopyAssignments; }
static size_t copies() { return copyConstructions() + copyAssignments(); }
static size_t moveConstructions() { return MoveConstructions; }
static size_t moveAssignments() { return MoveAssignments; }
static size_t moves() { return moveConstructions() + moveAssignments(); }
static size_t destructions() { return Destructions; }

static bool destructionsMatch() {
return destructions() == defaultConstructions() + copies() + moves();
}

static void reset() {
DefaultConstructions = 0;
CopyConstructions = 0;
CopyAssignments = 0;
MoveConstructions = 0;
MoveAssignments = 0;
Destructions = 0;
}

private:
static size_t DefaultConstructions;
static size_t CopyConstructions;
static size_t CopyAssignments;
static size_t MoveConstructions;
static size_t MoveAssignments;
static size_t Destructions;
};

#endif // ORC_RT_UNITTEST_COMMONTESTUTILS_H
85 changes: 85 additions & 0 deletions orc-rt/unittests/bind-test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
//===- bind-test.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 orc-rt's bind-test.h APIs.
//
//===----------------------------------------------------------------------===//

#include "CommonTestUtils.h"
#include "orc-rt/bind.h"
#include "orc-rt/move_only_function.h"
#include "gtest/gtest.h"

using namespace orc_rt;

static void voidVoid(void) {}

TEST(BindTest, VoidVoid) {
auto B = bind_front(voidVoid);
B();
}

static int addInts(int X, int Y) { return X + Y; }

TEST(BindTest, SimpleBind) {
auto Add1 = bind_front(addInts, 1);
EXPECT_EQ(Add1(2), 3);
}

TEST(BindTest, NoBoundArguments) {
auto Add = bind_front(addInts);
EXPECT_EQ(Add(1, 2), 3);
}

TEST(BindTest, NoFreeArguments) {
auto Add1And2 = bind_front(addInts, 1, 2);
EXPECT_EQ(Add1And2(), 3);
}

TEST(BindTest, LambdaCapture) {
auto Add1 = bind_front([](int X, int Y) { return X + Y; }, 1);
EXPECT_EQ(Add1(2), 3);
}

TEST(BindTest, MinimalMoves) {
OpCounter::reset();
{
auto B = bind_front([](OpCounter &O, int) {}, OpCounter());
B(0);
}
EXPECT_EQ(OpCounter::defaultConstructions(), 1U);
EXPECT_EQ(OpCounter::copies(), 0U);
EXPECT_EQ(OpCounter::moves(), 1U);
EXPECT_EQ(OpCounter::destructions(), 2U);
}

TEST(BindTest, MinimalCopies) {
OpCounter::reset();
{
OpCounter O;
auto B = bind_front([](OpCounter &O, int) {}, O);
B(0);
}
EXPECT_EQ(OpCounter::defaultConstructions(), 1U);
EXPECT_EQ(OpCounter::copies(), 1U);
EXPECT_EQ(OpCounter::moves(), 0U);
EXPECT_EQ(OpCounter::destructions(), 2U);
}

static int increment(int N) { return N + 1; }

TEST(BindTest, BindFunction) {
auto Op = bind_front([](int op(int), int arg) { return op(arg); }, increment);
EXPECT_EQ(Op(1), 2);
}

TEST(BindTest, BindTo_move_only_function) {
move_only_function<int(int, int)> Add = [](int X, int Y) { return X + Y; };
auto Add1 = bind_front(std::move(Add), 1);
EXPECT_EQ(Add1(2), 3);
}
Loading