Skip to content

Instantly share code, notes, and snippets.

@Porges
Last active January 11, 2016 19:53
Show Gist options
  • Save Porges/f4442bc7911f29dcdd89 to your computer and use it in GitHub Desktop.
Save Porges/f4442bc7911f29dcdd89 to your computer and use it in GitHub Desktop.
#include "stdafx.h"
#include <atomic>
#include <iostream>
#include <mutex>
#include <typeindex>
#include <typeinfo>
#include <unordered_map>
// here is the global mapping of type -> counts:
std::mutex counts_mutex; // protects 'counts':
std::unordered_map<std::type_index, std::atomic<std::uint64_t>*> counts;
// threadsafe way to get the mapping:
std::unordered_map<std::type_index, std::atomic<std::uint64_t>*> get_counts()
{
std::lock_guard<std::mutex> lock{ counts_mutex };
return counts;
}
template<class T>
class counted
{
// per-class count:
static std::atomic<std::uint64_t> count_;
const static std::uint64_t warn_threshold = 10000;
// adds the per-class count to the global mapping:
struct count_initializer
{
count_initializer()
{
std::lock_guard<std::mutex> lock{ counts_mutex };
counts[typeid(T)] = &count_;
}
};
protected:
counted() noexcept
{
// initialization happens threadsafely here:
static count_initializer init;
if (++count_ > warn_threshold)
{
std::cout << "BEEP BEEP BEEP" << std::endl;
}
}
~counted()
{
--count_;
}
};
// example:
class Base : counted<Base>
{
};
std::atomic<std::uint64_t> counted<Base>::count_{ 0 };
class Foo : counted<Foo>, Base
{
};
std::atomic<std::uint64_t> counted<Foo>::count_{ 0 };
class Bar : counted<Bar>, Base
{
};
std::atomic<std::uint64_t> counted<Bar>::count_{ 0 };
void print_counts()
{
std::cout << "Counts" << std::endl << "------" << std::endl;
auto counts = get_counts();
for (const auto& count : counts)
{
std::cout << count.first.name() << ": " << count.second->load() << std::endl;
}
std::cout << std::endl;
}
int main()
{
print_counts();
Foo foo;
Bar bar;
{
Bar bar2;
print_counts();
}
print_counts();
// Output is:
////Counts
////------
////Counts
////------
////class Foo : 1
////class Bar : 2
////Counts
////------
////class Foo : 1
////class Bar : 1
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment