Commit d9e3b6cc authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook Github Bot

SingletonRelaxedCountable

Summary: [Folly] `SingletonRelaxedCountable`, a convenience API around `SingletonRelaxedCounter` for counting instances of a type.

Reviewed By: ovoietsa

Differential Revision: D13686867

fbshipit-source-id: b2f7673e7e88c473337f66901c3e787d35eca6c6
parent 05c10a5b
......@@ -184,4 +184,58 @@ class SingletonRelaxedCounter {
}
};
template <typename Counted>
class SingletonRelaxedCountableAccess;
// SingletonRelaxedCountable
//
// A CRTP base class for making the instances of a type within a process be
// globally counted. The running counter is a relaxed counter.
//
// To avoid adding any new names from the base class to the counted type, the
// count is exposed via a separate type SingletonRelaxedCountableAccess.
//
// This type is a convenience interface around SingletonRelaxedCounter.
template <typename Counted>
class SingletonRelaxedCountable {
public:
SingletonRelaxedCountable() {
static_assert(
std::is_base_of<SingletonRelaxedCountable, Counted>::value, "non-crtp");
Counter::add(1);
}
~SingletonRelaxedCountable() {
static_assert(
std::is_base_of<SingletonRelaxedCountable, Counted>::value, "non-crtp");
Counter::sub(1);
}
SingletonRelaxedCountable(const SingletonRelaxedCountable&)
: SingletonRelaxedCountable() {}
SingletonRelaxedCountable(SingletonRelaxedCountable&&)
: SingletonRelaxedCountable() {}
SingletonRelaxedCountable& operator=(const SingletonRelaxedCountable&) =
default;
SingletonRelaxedCountable& operator=(SingletonRelaxedCountable&&) = default;
private:
friend class SingletonRelaxedCountableAccess<Counted>;
struct Tag;
using Counter = SingletonRelaxedCounter<size_t, Tag>;
};
// SingletonRelaxedCountableAccess
//
// Provides access to the running count of instances of a type using the CRTP
// base class SingletonRelaxedCountable.
template <typename Counted>
class SingletonRelaxedCountableAccess {
public:
static size_t count() {
return SingletonRelaxedCountable<Counted>::Counter::count();
}
};
} // namespace folly
......@@ -106,4 +106,50 @@ TEST_F(SingletonRelaxedCounterTest, MultithreadCorrectness) {
Counter::count();
}
TEST_F(SingletonRelaxedCounterTest, Countable) {
struct Object : SingletonRelaxedCountable<Object> {
std::shared_ptr<int> contained;
};
using Access = SingletonRelaxedCountableAccess<Object>;
EXPECT_EQ(0, Access::count());
{
Object a;
EXPECT_EQ(1, Access::count());
}
EXPECT_EQ(0, Access::count());
{
Object a;
Object b(a);
EXPECT_EQ(2, Access::count());
}
EXPECT_EQ(0, Access::count());
{
Object a;
Object b(std::move(a));
EXPECT_EQ(2, Access::count());
}
EXPECT_EQ(0, Access::count());
{
Object a;
Object b;
b = a;
EXPECT_EQ(2, Access::count());
}
EXPECT_EQ(0, Access::count());
{
Object a;
Object b;
b = std::move(a);
EXPECT_EQ(2, Access::count());
}
EXPECT_EQ(0, Access::count());
}
} // namespace folly
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment