Skip to content

Commit

Permalink
Merge pull request #503 from leapmotion/bug-autopacketallocators
Browse files Browse the repository at this point in the history
Fix custom allocator invocation
  • Loading branch information
gtremper committed May 8, 2015
2 parents bacec1d + 7f1af7f commit 93ee79f
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 1 deletion.
17 changes: 16 additions & 1 deletion autowiring/auto_arg.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,23 @@ template<class T, bool has_default>
struct auto_arg_ctor_helper<T, has_default, false> {
static_assert(has_default, "Cannot speculatively construct an output argument of type T, it doesn't have any available constructors");

template<void* (*)(size_t)>
struct fn {};

template<typename U>
static std::shared_ptr<U> Allocate(fn<&U::operator new>*) {
return std::shared_ptr<U>(new U);
}

template<typename U>
static std::shared_ptr<U> Allocate(...) {
return std::make_shared<U>();
}

static std::shared_ptr<T> arg(AutoPacket&) {
return std::make_shared<T>();
// Use make shared, if we can; if static new is present on this type, though, then we have to use
// the uglier two-part construction syntax
return Allocate<T>(nullptr);
}
};

Expand Down
41 changes: 41 additions & 0 deletions src/autowiring/test/AutoFilterConstructRulesTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,44 @@ TEST_F(AutoFilterConstructRulesTest, CanAcceptUndefinedSharedPointerInput) {
AutoRequired<AcceptsUnnamedExternalClass> auec;
AutoRequired<AcceptsUnnamedExternalClassSharedPtr> auecsp;
}

class HasCustomNewFunction {
public:
static bool s_invoked;

static void* operator new(size_t ncb){
s_invoked = true;

uint8_t* pRetVal = ::new uint8_t[ncb];
for (size_t i = 0; i < ncb; i++)
pRetVal[i] = (i + 1) * 101;
return pRetVal;
}

uint8_t data[128];
};

bool HasCustomNewFunction::s_invoked = false;

class GeneratesCustomAllocatedType {
public:
void AutoFilter(HasCustomNewFunction&) {}
};

TEST_F(AutoFilterConstructRulesTest, CorrectlyCallsCustomAllocator) {
AutoRequired<AutoPacketFactory> factory;
AutoRequired<GeneratesCustomAllocatedType>();

ASSERT_FALSE(HasCustomNewFunction::s_invoked) << "Custom allocator was invoked prematurely";
auto packet = factory->NewPacket();
auto* phcnf = packet->GetShared<HasCustomNewFunction>();
auto& hcnf = *phcnf;
ASSERT_TRUE(phcnf && hcnf) << "Decoration with custom allocator not present on a packet as expected";
ASSERT_TRUE(HasCustomNewFunction::s_invoked) << "Custom new allocator was not invoked as expected";

for (size_t i = 0; i < 128; i++)
ASSERT_EQ(
static_cast<uint8_t>((i + 1) * 101),
hcnf->data[i]
) << "Custom new allocator did not fill space, mismatch at offset " << i;
}

0 comments on commit 93ee79f

Please sign in to comment.