Common ODB Runtime Library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
pointer-traits.hxx
Go to the documentation of this file.
1 // file : odb/pointer-traits.hxx
2 // copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC
3 // license : GNU GPL v2; see accompanying LICENSE file
4 
5 #ifndef ODB_POINTER_TRAITS_HXX
6 #define ODB_POINTER_TRAITS_HXX
7 
8 #include <odb/pre.hxx>
9 
10 #include <new> // operators new/delete
11 #include <memory> // std::auto_ptr, std::unique_ptr, std::shared_ptr/weak_ptr
12 #include <cstddef> // std::size_t
13 
14 #include <odb/details/config.hxx> // ODB_CXX11
15 #include <odb/details/meta/remove-const.hxx>
16 
17 namespace odb
18 {
20  {
21  pk_raw, // Raw pointer or equivalent (i.e., unmanaged).
22  pk_unique, // Smart pointer that doesn't support sharing.
23  pk_shared, // Smart pointer that supports sharing.
24  pk_weak // Weak counterpart for shared pointer.
25  };
26 
27  template <typename P>
29 
30  //
31  // Standard pointer guards.
32  //
33 
34  // Raw pointer guard.
35  //
36  template <typename P>
38  {
39  public:
40  ~raw_ptr_guard () {delete p_;}
41  raw_ptr_guard (): p_ (0) {}
42 
43  explicit
44  raw_ptr_guard (P p): p_ (p) {}
45 
46  void
47  release () {p_ = 0;}
48 
49  void
50  reset (P p = 0) {delete p_; p_ = p;}
51 
52  private:
53  P p_;
54  };
55 
56  // No-op pointer guard for smart pointers.
57  //
58  template <typename P>
60  {
61  public:
63 
64  explicit
65  smart_ptr_guard (const P&) {}
66 
67  void
68  release () {}
69 
70  void
71  reset () {}
72 
73  void
74  reset (const P&) {}
75  };
76 
77  // Specialization for raw pointers.
78  //
79  template <typename T>
80  class pointer_traits<T*>
81  {
82  public:
83  static const pointer_kind kind = pk_raw;
84  static const bool lazy = false;
85 
86  typedef T element_type;
87  typedef T* pointer_type;
88  typedef const T* const_pointer_type;
89  typedef typename odb::details::meta::remove_const<T>::result*
92 
93  // Return raw pointer to the pointed-to element, including NULL.
94  //
95  static element_type*
96  get_ptr (pointer_type p)
97  {
98  return p;
99  }
100 
101  // Return reference to the pointed-to element.
102  //
103  static element_type&
104  get_ref (pointer_type p)
105  {
106  return *p;
107  }
108 
109  // Return true if the pointer is NULL.
110  //
111  static bool
112  null_ptr (pointer_type p)
113  {
114  return p == 0;
115  }
116 
117  // Casts.
118  //
119  static unrestricted_pointer_type
120  const_pointer_cast (pointer_type p)
121  {
122  return const_cast<unrestricted_pointer_type> (p);
123  }
124 
125  template <typename T1>
126  static T1*
127  static_pointer_cast (pointer_type p)
128  {
129  return static_cast<T1*> (p);
130  }
131 
132  template <typename T1>
133  static T1*
134  dynamic_pointer_cast (pointer_type p)
135  {
136  return dynamic_cast<T1*> (p);
137  }
138 
139  public:
140  // Allocate memory for an element that will be managed by this
141  // pointer.
142  //
143  static void*
144  allocate (std::size_t n)
145  {
146  return operator new (n);
147  }
148 
149  // Free memory allocated for an element. This functions is only
150  // called if the constructor of the element being created fails.
151  // Otherwise, the pointer (or guard) is used to delete the object
152  // and free the memory. This behavior is identical to the one
153  // used by operator delete overloading.
154  //
155  static void
156  free (void* p)
157  {
158  operator delete (p);
159  }
160  };
161 
162  // Specialization for std::auto_ptr.
163  //
164  template <typename T>
165  class pointer_traits< std::auto_ptr<T> >
166  {
167  public:
168  static const pointer_kind kind = pk_unique;
169  static const bool lazy = false;
170 
171  typedef T element_type;
172  typedef std::auto_ptr<element_type> pointer_type;
173  typedef std::auto_ptr<const element_type> const_pointer_type;
175 
176  static element_type*
178  {
179  return p.get ();
180  }
181 
182  static element_type&
184  {
185  return *p;
186  }
187 
188  static bool
190  {
191  return p.get () == 0;
192  }
193 
194  // const_pointer_cast() is not provided.
195  //
196 
197  // Note: transfers ownership.
198  //
199  template <typename T1>
200  static std::auto_ptr<T1>
202  {
203  return std::auto_ptr<T1> (static_cast<T1*> (p.release ()));
204  }
205 
206  // Note: transfers ownership if successful.
207  //
208  template <typename T1>
209  static std::auto_ptr<T1>
211  {
212  T1* p1 (dynamic_cast<T1*> (p.get ()));
213 
214  if (p1 != 0)
215  p.release ();
216 
217  return std::auto_ptr<T1> (p1);
218  }
219 
220  public:
221  static void*
222  allocate (std::size_t n)
223  {
224  return operator new (n);
225  }
226 
227  static void
228  free (void* p)
229  {
230  operator delete (p);
231  }
232  };
233 
234 #ifdef ODB_CXX11
235 
236  // Specialization for C++11 std::unique_ptr.
237  //
238  template <typename T, typename D>
239  class pointer_traits<std::unique_ptr<T, D>>
240  {
241  public:
242  static const pointer_kind kind = pk_unique;
243  static const bool lazy = false;
244 
245  typedef T element_type;
246  typedef std::unique_ptr<element_type, D> pointer_type;
247  typedef std::unique_ptr<const element_type, D> const_pointer_type;
248  typedef smart_ptr_guard<pointer_type> guard;
249 
250  static element_type*
251  get_ptr (const pointer_type& p)
252  {
253  return p.get ();
254  }
255 
256  static element_type&
257  get_ref (const pointer_type& p)
258  {
259  return *p;
260  }
261 
262  static bool
263  null_ptr (const pointer_type& p)
264  {
265  return !p;
266  }
267 
268  // const_pointer_cast() is not provided.
269  //
270 
271  // Note: transfers ownership.
272  //
273  template <typename T1>
274  static std::unique_ptr<T1>
275  static_pointer_cast (pointer_type& p)
276  {
277  return std::unique_ptr<T1> (static_cast<T1*> (p.release ()));
278  }
279 
280  // Note: transfers ownership if successful.
281  //
282  template <typename T1>
283  static std::unique_ptr<T1>
284  dynamic_pointer_cast (pointer_type& p)
285  {
286  T1* p1 (dynamic_cast<T1*> (p.get ()));
287 
288  if (p1 != 0)
289  p.release ();
290 
291  return std::unique_ptr<T1> (p1);
292  }
293 
294  public:
295  static void*
296  allocate (std::size_t n)
297  {
298  return operator new (n);
299  }
300 
301  static void
302  free (void* p)
303  {
304  operator delete (p);
305  }
306  };
307 
308  // Specialization for C++11 std::shared_ptr.
309  //
310  template <typename T>
311  class pointer_traits<std::shared_ptr<T>>
312  {
313  public:
314  static const pointer_kind kind = pk_shared;
315  static const bool lazy = false;
316 
317  typedef T element_type;
318  typedef std::shared_ptr<element_type> pointer_type;
319  typedef std::shared_ptr<const element_type> const_pointer_type;
320  typedef typename odb::details::meta::remove_const<element_type>::result
321  unrestricted_element_type;
322  typedef std::shared_ptr<unrestricted_element_type>
323  unrestricted_pointer_type;
324  typedef smart_ptr_guard<pointer_type> guard;
325 
326  static element_type*
327  get_ptr (const pointer_type& p)
328  {
329  return p.get ();
330  }
331 
332  static element_type&
333  get_ref (const pointer_type& p)
334  {
335  return *p;
336  }
337 
338  static bool
339  null_ptr (const pointer_type& p)
340  {
341  return !p;
342  }
343 
344  static unrestricted_pointer_type
345  const_pointer_cast (const pointer_type& p)
346  {
347  return std::const_pointer_cast<unrestricted_element_type> (p);
348  }
349 
350  template <typename T1>
351  static std::shared_ptr<T1>
352  static_pointer_cast (const pointer_type& p)
353  {
354  return std::static_pointer_cast<T1> (p);
355  }
356 
357  template <typename T1>
358  static std::shared_ptr<T1>
359  dynamic_pointer_cast (const pointer_type& p)
360  {
361  return std::dynamic_pointer_cast<T1> (p);
362  }
363 
364  public:
365  static void*
366  allocate (std::size_t n)
367  {
368  return operator new (n);
369  }
370 
371  static void
372  free (void* p)
373  {
374  operator delete (p);
375  }
376  };
377 
378  // Specialization for C++11 std::weak_ptr.
379  //
380  template <typename T>
381  class pointer_traits<std::weak_ptr<T>>
382  {
383  public:
384  static const pointer_kind kind = pk_weak;
385  static const bool lazy = false;
386 
387  typedef T element_type;
388  typedef std::weak_ptr<element_type> pointer_type;
389  typedef std::shared_ptr<element_type> strong_pointer_type;
390 
391  static strong_pointer_type
392  lock (const pointer_type& p)
393  {
394  return p.lock ();
395  }
396  };
397 
398 #endif // ODB_CXX11
399 
400 }
401 
402 #include <odb/post.hxx>
403 
404 #endif // ODB_POINTER_TRAITS_HXX
static T1 * dynamic_pointer_cast(pointer_type p)
Definition: pointer-traits.hxx:134
Definition: pointer-traits.hxx:37
static void * allocate(std::size_t n)
Definition: pointer-traits.hxx:222
Definition: pointer-traits.hxx:24
Definition: pointer-traits.hxx:23
smart_ptr_guard(const P &)
Definition: pointer-traits.hxx:65
static std::auto_ptr< T1 > dynamic_pointer_cast(pointer_type &p)
Definition: pointer-traits.hxx:210
const T * const_pointer_type
Definition: pointer-traits.hxx:88
raw_ptr_guard(P p)
Definition: pointer-traits.hxx:44
static T1 * static_pointer_cast(pointer_type p)
Definition: pointer-traits.hxx:127
Definition: pointer-traits.hxx:28
T element_type
Definition: pointer-traits.hxx:171
void release()
Definition: pointer-traits.hxx:68
static element_type & get_ref(const pointer_type &p)
Definition: pointer-traits.hxx:183
static element_type & get_ref(pointer_type p)
Definition: pointer-traits.hxx:104
static bool null_ptr(const pointer_type &p)
Definition: pointer-traits.hxx:189
void reset(P p=0)
Definition: pointer-traits.hxx:50
std::auto_ptr< element_type > pointer_type
Definition: pointer-traits.hxx:172
void reset(const P &)
Definition: pointer-traits.hxx:74
smart_ptr_guard()
Definition: pointer-traits.hxx:62
Definition: pointer-traits.hxx:59
T element_type
Definition: pointer-traits.hxx:86
odb::details::meta::remove_const< T >::result * unrestricted_pointer_type
Definition: pointer-traits.hxx:90
static unrestricted_pointer_type const_pointer_cast(pointer_type p)
Definition: pointer-traits.hxx:120
static element_type * get_ptr(const pointer_type &p)
Definition: pointer-traits.hxx:177
static std::auto_ptr< T1 > static_pointer_cast(pointer_type &p)
Definition: pointer-traits.hxx:201
static void free(void *p)
Definition: pointer-traits.hxx:228
std::auto_ptr< const element_type > const_pointer_type
Definition: pointer-traits.hxx:173
raw_ptr_guard()
Definition: pointer-traits.hxx:41
T * pointer_type
Definition: pointer-traits.hxx:87
static void * allocate(std::size_t n)
Definition: pointer-traits.hxx:144
raw_ptr_guard< pointer_type > guard
Definition: pointer-traits.hxx:91
static element_type * get_ptr(pointer_type p)
Definition: pointer-traits.hxx:96
~raw_ptr_guard()
Definition: pointer-traits.hxx:40
Definition: pointer-traits.hxx:21
void release()
Definition: pointer-traits.hxx:47
void reset()
Definition: pointer-traits.hxx:71
static void free(void *p)
Definition: pointer-traits.hxx:156
static bool null_ptr(pointer_type p)
Definition: pointer-traits.hxx:112
smart_ptr_guard< pointer_type > guard
Definition: pointer-traits.hxx:174
Definition: pointer-traits.hxx:22
pointer_kind
Definition: pointer-traits.hxx:19