Skip to content

Instantly share code, notes, and snippets.

@Hebali
Last active June 25, 2017 19:36
Show Gist options
  • Save Hebali/a2e9bc9116b327d9730cb3434893cc9c to your computer and use it in GitHub Desktop.
Save Hebali/a2e9bc9116b327d9730cb3434893cc9c to your computer and use it in GitHub Desktop.
Singleton Cache Manager Using Custom Smart Pointer Deleters
/*
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