Diffstat (limited to 'include/konforka/resource_pile.h') (more/less context) (ignore whitespace changes)
-rw-r--r-- | include/konforka/resource_pile.h | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/include/konforka/resource_pile.h b/include/konforka/resource_pile.h new file mode 100644 index 0000000..d76a07b --- a/dev/null +++ b/include/konforka/resource_pile.h @@ -0,0 +1,118 @@ +#ifndef __KONFORKA_RESOURCE_PILE_H +#define __KONFORKA_RESOURCE_PILE_H + +#include <map> +#include <konforka/responsible_wrapper.h> + +/** + * @file + * @brief resource-piling base support. + * + * Base for implementing resource-piling. + */ + +namespace konforka { + using std::multimap; + using std::pair; + + /** + * @brief template base class for resource piling. + * + * @param key_t the type used for keying resources. + * @param value_t the type of resource itself. + * @param factory_t the factory class, providing value_t allocate(key_t) + * static member. + */ + template<typename key_t,typename value_t,typename factory_t> + class resource_pile_base : public responsible_wrapper<value_t> { + /** + * @brief the type of the pile container itself. + */ + typedef multimap<key_t,value_t> pile_t; + /* + * @brief the pile of resources. + */ + static pile_t pile; + public: + /** + * @brief stored value for the key associated with the resource + * contained. + */ + key_t _key; + + /** + * @brief default constructor fetches or allocates resource. + * + * @param k the key for resource. + * @see allocate + */ + resource_pile_base(const key_t& k) { + allocate(k); + } + /** + * @brief destructor releases the resource back to pile. + */ + virtual ~resource_pile_base() { this->drop(); } + + /** + * @brief this is where the resource is handed back to pile. + */ + void release() { + pile.insert(pair<key_t,value_t>(_key,this->opkele)); + } + + /** + * @brief fetch from pile or allocate the resource. + * + * Try to see if we have a piled resource keyed to the argument. If + * we do -- fetch it from the pile, otherwise allocate anew. + * + * @param k the key for resource. + */ + void allocate(const key_t& k) { + this->drop(); + typename pile_t::iterator i = pile.find(k); + if(i==pile.end()) { + this->attach(factory_t::allocate(k)); + }else{ + this->attach(i->second); + try{ pile.erase(i); }catch(...){ _key = k; throw; } + } + _key = k; + } + + }; + + template<typename key_t,typename value_t,typename factory_t> + typename resource_pile_base<key_t,value_t,factory_t>::pile_t + resource_pile_base<key_t,value_t,factory_t>::pile; + + /** + * @brief the generic single parameter new-based resource factory. + * + * The generic resource factory using new as a way to allocate resource + * using the single-parameter constructor. + * + * @param key_t the key type. + * @param value_t the resource type. + * + * @see resource_pile_base + */ + template<typename key_t,typename value_t> + struct resource_pile_generic_ptr_factory { + public: + /** + * @brief allocate the resource using new. + * + * @param k the key. + * @return pointer to the newly allocated object. + */ + static value_t *allocate(const key_t& k) { + return new value_t(k); + } + }; + +} + +#endif /* __KONFORKA_RESOURCE_PILE_H */ +/* vim:set ft=cpp: */ |