Created
June 5, 2018 15:31
-
-
Save alepez/0cd9e8d9a17ee4ac26c30b0464813eb8 to your computer and use it in GitHub Desktop.
weak-ptr-global (global is bad practice, but at least this is automatically released)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cassert> | |
#include <iostream> | |
#include <memory> | |
#include <mutex> | |
#include <string> | |
#include <unordered_map> | |
template <typename T> | |
std::shared_ptr<T> get_global(int id) { | |
using Map = std::unordered_map<int, std::weak_ptr<T>>; | |
static std::mutex mutex; | |
static Map instances; | |
std::lock_guard<std::mutex> lock(mutex); | |
/* Find if already created */ | |
if (instances.count(id)) { | |
auto sptr = instances[id].lock(); | |
/* Is it still valid? */ | |
if (sptr) return sptr; | |
} | |
/* Never created or not valid, create a shared ptr */ | |
auto sptr = std::make_shared<T>(); | |
/* Keep only the weak ptr */ | |
instances[id] = sptr; | |
/* Return the shared ptr, so lifetime is managed by caller */ | |
return sptr; | |
} | |
void check(int id, const std::string& expected) { | |
auto r = get_global<std::string>(id); | |
assert(*r == expected); | |
} | |
void print(int id) { | |
auto inst = *get_global<std::string>(id); | |
std::cout << inst << std::endl; | |
} | |
int main() { | |
{ | |
auto s = get_global<std::string>(0); | |
*s = "test"; | |
check(0, "test"); | |
print(0); | |
/* ss is bound to id 0 */ | |
auto ss = get_global<std::string>(0); | |
*ss = "foo"; | |
check(0, "foo"); | |
print(0); | |
/* t has a different id, so it is a different resource */ | |
auto t = get_global<std::string>(1); | |
*t = "ciao"; | |
check(1, "ciao"); | |
print(1); | |
check(0, "foo"); | |
print(0); | |
} | |
/* s is out of scope, its resource is released */ | |
{ | |
/* q is bound to id 0, but it is a new resource, because previous has been | |
* released */ | |
auto q = get_global<std::string>(0); | |
check(0, ""); | |
print(0); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment