[ManagedStatic] Add a way to pass custom creators/deleters.

Also add a test case verifying that nested ManagedStatics work correctly.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@304155 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Benjamin Kramer 2017-05-29 14:05:26 +00:00
parent cf2a64aaaf
commit 10f535273f
2 changed files with 46 additions and 3 deletions

View File

@ -59,14 +59,15 @@ public:
/// libraries that link in LLVM components) and for making destruction be
/// explicit through the llvm_shutdown() function call.
///
template<class C>
template <class C, void *(*Creator)() = object_creator<C>,
void (*Deleter)(void *) = object_deleter<C>::call>
class ManagedStatic : public ManagedStaticBase {
public:
// Accessors.
C &operator*() {
void *Tmp = Ptr.load(std::memory_order_acquire);
if (!Tmp)
RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
RegisterManagedStatic(Creator, Deleter);
return *static_cast<C *>(Ptr.load(std::memory_order_relaxed));
}
@ -76,7 +77,7 @@ public:
const C &operator*() const {
void *Tmp = Ptr.load(std::memory_order_acquire);
if (!Tmp)
RegisterManagedStatic(object_creator<C>, object_deleter<C>::call);
RegisterManagedStatic(Creator, Deleter);
return *static_cast<C *>(Ptr.load(std::memory_order_relaxed));
}

View File

@ -57,4 +57,46 @@ TEST(Initialize, MultipleThreads) {
}
#endif
namespace NestedStatics {
static ManagedStatic<int> Ms1;
struct Nest {
Nest() {
++(*Ms1);
}
~Nest() {
assert(Ms1.isConstructed());
++(*Ms1);
}
};
static ManagedStatic<Nest> Ms2;
TEST(ManagedStaticTest, NestedStatics) {
EXPECT_FALSE(Ms1.isConstructed());
EXPECT_FALSE(Ms2.isConstructed());
*Ms2;
EXPECT_TRUE(Ms1.isConstructed());
EXPECT_TRUE(Ms2.isConstructed());
llvm_shutdown();
EXPECT_FALSE(Ms1.isConstructed());
EXPECT_FALSE(Ms2.isConstructed());
}
} // namespace NestedStatics
namespace CustomCreatorDeletor {
static void *CustomCreate() {
void *Mem = std::malloc(sizeof(int));
*((int *)Mem) = 42;
return Mem;
}
static ManagedStatic<int, CustomCreate, std::free> Custom;
TEST(ManagedStaticTest, CustomCreatorDeletor) {
EXPECT_EQ(42, *Custom);
llvm_shutdown();
EXPECT_FALSE(Custom.isConstructed());
}
} // namespace CustomCreatorDeletor
} // anonymous namespace