1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
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: */
|