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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
|
/*************************************************
* mixin class to force that all instances *
* allocated on the free store are referenced *
* through smart pointers. *
* (C) 2007 Christoph Ludwig *
* ludwig@fh-worms.de *
*************************************************/
#ifndef BOTAN_FREESTORE_H__
#define BOTAN_FREESTORE_H__
#if defined(BOTAN_USE_TR1_SHARED_PTR)
#include <tr1/memory>
#elif defined(BOTAN_USE_BOOST_TR1_SHARED_PTR)
#include <boost/tr1/memory.hpp>
#else
#error "Please choose a shared_ptr implementation"
#endif
// Boost headers
#include <boost/preprocessor/arithmetic/inc.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/stringize.hpp>
#ifndef BOTAN_CREATE_PTR_MAX_ARITY
#define BOTAN_CREATE_PTR_MAX_ARITY 10
#endif
namespace Botan {
template<typename T>
class SharedPtrConverter
{
public:
typedef std::tr1::shared_ptr<T> SharedPtr;
SharedPtrConverter() : ptr() {};
SharedPtrConverter(SharedPtrConverter const& other)
: ptr(other.ptr) {};
template<typename Ptr>
SharedPtrConverter(Ptr p)
: ptr(p) {};
SharedPtr const& get_ptr() const { return this->ptr; }
SharedPtr get_ptr() { return this->ptr; }
SharedPtr const& get_shared() const { return this->ptr; }
SharedPtr get_shared() { return this->ptr; }
private:
SharedPtr ptr;
};
/*
* Create an object of type T on the free store by means of the
* default constructor and return an auto_ptr to this object.
*/
template <class T>
std::auto_ptr<T> create_auto_ptr()
{
T* raw = new T();
return std::auto_ptr<T>(raw);
}
/*
* Create an object of type T on the free store by means of the
* default constructor and return a shared_ptr to this object.
*/
template <class T>
std::tr1::shared_ptr<T> create_shared_ptr()
{
T* raw = new T();
return std::tr1::shared_ptr<T>(raw);
}
/*
* Provide overloads of create_auto_ptr and create_shared_ptr for up to
* BOTAN_CREATE_PTR_MAX_ARITY constructor parameters.
*
* The code below defines
* template<class T, typename A1>
* std::auto_ptr<T> create_auto_ptr(A1 p1);
*
* template<class T, typename A1, typename A2>
* std::auto_ptr<T> create_auto_ptr(A1 p1, A2 p2);
*
* and so on up to
*
* template<class T, typename A1, typename A2, ..., typename An>
* std::auto_ptr<T> create_auto_ptr(A1 p1, A2 p2, ..., An pn);
*
* where n = BOTAN_CREATE_PTR_MAX_ARITY. The code also defines similar
* function template overloads for create_shared_pt.
*
* The idea for the preprocessor code is taken from:
* Grenyer, Paul: "All Heap No Leak". Overload, Issue 60, ACCU, Sept. 2004.
* Available at <URL:http://www.accu.org/index.php/journals/306>.
*/
// Doxygen cannot handle the preprocessor code
# ifndef DOXYGEN_IS_PARSING
# define BOTAN_CREATE_PTR(z, n, _) \
template<class T, \
BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n), typename A)> \
std::auto_ptr<T> \
create_auto_ptr(BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_INC(n), A, p)) { \
T* raw = new T(BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n), p)); \
return std::auto_ptr<T>(raw); \
} \
\
template<class T, \
BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n), typename A)> \
std::tr1::shared_ptr<T> \
create_shared_ptr(BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_INC(n), A, p)) { \
T* raw = new T(BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n), p)); \
return std::tr1::shared_ptr<T>(raw); \
} \
/**/
BOOST_PP_REPEAT(BOTAN_CREATE_PTR_MAX_ARITY, BOTAN_CREATE_PTR, ~)
# if 0
; // make emacs' and other editors' auto-indentation happy...
# endif
# undef BOTAN_CREATE_PTR
# else
//! Preprocessor generated factory functions that return auto_ptr<T>
template<typename T, typename P1, typename P2, typename P3, ... >
std::auto_ptr<T> create_auto_ptr(P1 p1, P2 p2, P3 p3, ...);
//! Preprocessor generated factory functions that return shared_ptr<T>
template<typename T, typename P1, typename P2, typename P3, ... >
std::tr1::shared_ptr<T> create_shared_ptr(P1 p1, P2 p2, P3 p3, ...);
# endif // DOXYGEN_IS_PARSING
/*
* Freestore enforces that all objects (including objects of derived types)
* can no longer be allocated on the free store by means of the
* new (or new[]) operator, but only via one of the overloads
* of function template Botan::create_ptr.
*/
class Freestore
{
private:
static
inline
void* operator new(std::size_t size) throw (std::bad_alloc)
{
return ::operator new(size);
}
static
inline
void* operator new[](std::size_t size) throw (std::bad_alloc)
{
return ::operator new[](size);
}
template <class T>
friend
std::auto_ptr<T> create_auto_ptr();
template <class T>
friend
std::tr1::shared_ptr<T> create_shared_ptr();
# ifndef DOXYGEN_IS_PARSING
# define BOTAN_FREESTORE_FRIEND_CREATE_PTR(z, n, _) \
template<class T, \
BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n), typename A)> \
friend \
std::auto_ptr<T> \
create_auto_ptr(BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_INC(n), A, p)); \
\
template<class T, \
BOOST_PP_ENUM_PARAMS(BOOST_PP_INC(n), typename A)> \
friend \
std::tr1::shared_ptr<T> \
create_shared_ptr(BOOST_PP_ENUM_BINARY_PARAMS(BOOST_PP_INC(n), A, p)); \
/**/
BOOST_PP_REPEAT(BOTAN_CREATE_PTR_MAX_ARITY, BOTAN_FREESTORE_FRIEND_CREATE_PTR, ~)
# if 0
; // make emacs' auto-indentation happy...
# endif
# undef BOTAN_FREESTORE_FRIEND_CREATE_PTR
# else
template<typename T, typename P1, typename P2, typename P3, ... >
friend
std::auto_ptr<T> create_auto_ptr(P1 p1, P2 p2, P3 p3, ...);
template<typename T, typename P1, typename P2, typename P3, ... >
friend
std::tr1::shared_ptr<T> create_shared_ptr(P1 p1, P2 p2, P3 p3, ...);
# endif // DOXYGEN_IS_PARSING
public:
// implicitly defined constructors and assignment operator are
// fine.
};
}
#endif
|