summaryrefslogtreecommitdiffabout
path: root/include/konforka/resource_pile.h
Side-by-side diff
Diffstat (limited to 'include/konforka/resource_pile.h') (more/less context) (ignore whitespace changes)
-rw-r--r--include/konforka/resource_pile.h118
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: */