Last active
June 25, 2017 19:36
-
-
Save Hebali/a2e9bc9116b327d9730cb3434893cc9c to your computer and use it in GitHub Desktop.
Singleton Cache Manager Using Custom Smart Pointer Deleters
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
/* | |
CONCEPT SKETCH: | |
Singleton Cache Manager Using Custom Smart Pointer Deleters | |
by Patrick Hebron | |
*/ | |
#include <iostream> | |
#include <memory> | |
#include <map> | |
typedef std::shared_ptr<class Object> ObjectRef; | |
typedef std::shared_ptr<class Derived> DerivedRef; | |
class Object | |
{ | |
public: | |
std::string name; | |
Object(const std::string& n = "") : name( n ) { std::cout << "Object(" << name << ")" << std::endl; } | |
virtual ~Object() { std::cout << "~Object(" << name << ")" << std::endl; } | |
virtual void init() { std::cout << "Object::init(" << name << ")" << std::endl; } | |
void testA() { std::cout << "Object::testA(" << name << ")" << std::endl; } | |
virtual void testB() { std::cout << "Object::testB(" << name << ")" << std::endl; } | |
}; | |
class Derived : public Object | |
{ | |
public: | |
Derived(const std::string& n = "") : Object( n ) { std::cout << "Derived(" << name << ")" << std::endl; } | |
~Derived() { std::cout << "~Derived(" << name << ")" << std::endl; } | |
void testB() { std::cout << "Derived::testB(" << name << ")" << std::endl; } | |
}; | |
/** @brief cache manager singleton class */ | |
struct CacheManager | |
{ | |
private: | |
std::map<uintptr_t,int> mItems; | |
/** @brief default constructor */ | |
CacheManager() | |
{ | |
/* no-op */ | |
} | |
/** @brief destructor */ | |
~CacheManager() | |
{ | |
/* no-op */ | |
} | |
bool cache_contains(uintptr_t key) const | |
{ | |
return ( mItems.find( key ) != mItems.cend() ); | |
} | |
void cache_remove(uintptr_t key) | |
{ | |
auto needle = mItems.find( key ); | |
if( needle != mItems.end() ) | |
mItems.erase( needle ); | |
} | |
void cache_insert(uintptr_t key, int value) | |
{ | |
mItems[ key ] = value; | |
} | |
int cache_retrieve(uintptr_t key) const | |
{ | |
auto needle = mItems.find( key ); | |
if( needle != mItems.cend() ) | |
return needle->second; | |
throw std::runtime_error( "Cache manager could not retrieve item." ); | |
} | |
public: | |
/** @brief instance getter */ | |
static CacheManager& Get() | |
{ | |
static CacheManager instance; | |
return instance; | |
} | |
/** @brief copy constructor */ | |
CacheManager(CacheManager const&) = delete; | |
/** @brief move constructor */ | |
CacheManager(CacheManager&&) = delete; | |
/** @brief copy assignment operator */ | |
CacheManager& operator=(CacheManager const&) = delete; | |
/** @brief move assignment operator */ | |
CacheManager& operator=(CacheManager &&) = delete; | |
static uintptr_t cast_key(const Object* obj) | |
{ | |
return reinterpret_cast<uintptr_t>( obj ); | |
} | |
static bool contains(const Object* key) | |
{ | |
std::cout << "CacheManager::contains(" << key->name << ")" << std::endl; | |
return Get().cache_contains( cast_key( key ) ); | |
} | |
static void remove(const Object* key) | |
{ | |
std::cout << "CacheManager::remove(" << key->name << ")" << std::endl; | |
Get().cache_remove( cast_key( key ) ); | |
} | |
static void insert(const Object* key, int value) | |
{ | |
std::cout << "CacheManager::insert(" << key->name << ")" << std::endl; | |
Get().cache_insert( cast_key( key ), value ); | |
} | |
static int retrieve(const Object* key) | |
{ | |
std::cout << "CacheManager::retrieve(" << key->name << ")" << std::endl; | |
return Get().cache_retrieve( cast_key( key ) ); | |
} | |
}; | |
static void CachedObjectDeleter(Object* item) | |
{ | |
CacheManager::remove( item ); | |
std::cout << "CachedObjectDeleter(" << item->name << ")" << std::endl; | |
delete item; | |
} | |
using namespace std; | |
int main(int argc, const char * argv[]) | |
{ | |
std::cout << std::string( 20, '-' ) << std::endl; | |
{ | |
ObjectRef item = ObjectRef( new Object("item0") ); | |
item->testA(); | |
item->testB(); | |
} | |
std::cout << std::string( 20, '-' ) << std::endl; | |
{ | |
ObjectRef item = ObjectRef( new Object("item1"), CachedObjectDeleter ); | |
item->testA(); | |
item->testB(); | |
} | |
std::cout << std::string( 20, '-' ) << std::endl; | |
{ | |
ObjectRef item = ObjectRef( new Derived("item2") ); | |
CacheManager::insert( item.get(), 2 ); | |
item->testA(); | |
item->testB(); | |
} | |
std::cout << std::string( 20, '-' ) << std::endl; | |
{ | |
ObjectRef item = ObjectRef( new Derived("item3"), CachedObjectDeleter ); | |
CacheManager::insert( item.get(), 3 ); | |
item->testA(); | |
item->testB(); | |
} | |
std::cout << std::string( 20, '-' ) << std::endl; | |
{ | |
DerivedRef item = DerivedRef( new Derived("item4") ); | |
CacheManager::insert( item.get(), 4 ); | |
item->testA(); | |
item->testB(); | |
} | |
std::cout << std::string( 20, '-' ) << std::endl; | |
{ | |
DerivedRef item = DerivedRef( new Derived("item5"), CachedObjectDeleter ); | |
CacheManager::insert( item.get(), 5 ); | |
item->testA(); | |
item->testB(); | |
} | |
std::cout << std::string( 20, '-' ) << std::endl; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment