root/hydranode/hnbase/unchain_ptr.h

Revision 2613, 2.6 kB (checked in by madcat, 3 years ago)

Copyright notice update for 2006.

Line 
1 /* Copyright 2005-2006 Alo Sarv
2  * Distributed under the Boost Software Licence, Version 1.0
3  * (See accompanying file LICENCE_1_0.txt or copy at
4  * http://www.boost.org/LICENSE_1_0.txt)
5  */
6
7 #ifndef __UNCHAIN_PTR_H__
8 #define __UNCHAIN_PTR_H__
9
10 #include <boost/shared_ptr.hpp>
11 #include <boost/intrusive_ptr.hpp>
12 #include <boost/ref.hpp>
13 #include <boost/type_traits.hpp>
14 #include <boost/mpl/if.hpp>
15
16 namespace Utils {
17 namespace detail {
18
19 template<typename Class>
20 struct unchainptr_impl {
21         // non-const overloads
22         Class& operator()(Class &x) const { return x; }
23
24         template<typename ChainedPtr>
25         Class& operator()(ChainedPtr &x) const {
26                 return operator()(*x);
27         }
28
29         Class& operator()(boost::reference_wrapper<Class> &x) const {
30                 return operator()(x.get());
31         }
32 };
33
34 template<typename Class>
35 struct unchainptr_const_impl {
36         // const overloads
37         const Class& operator()(const Class &x) const { return x; }
38
39         template<typename ChainedPtr>
40         const Class& operator()(const ChainedPtr &x) const {
41                 return operator()(*x);
42         }
43
44         const Class& operator()(
45                 const boost::reference_wrapper<const Class> &x
46         ) const {
47                 return operator()(x.get());
48         }
49 };
50
51 template<typename T>
52 struct get_type {
53         typedef T type;
54 };
55 template<typename T>
56 struct get_type<T*> {
57         typedef typename get_type<T>::type type;
58 };
59 template<typename T>
60 struct get_type<T *const> {
61         typedef typename get_type<T>::type type;
62 };
63 template<typename T>
64 struct get_type<T&> {
65         typedef typename get_type<T>::type type;
66 };
67 template<typename T>
68 struct get_type<boost::shared_ptr<T> > {
69         typedef typename get_type<T>::type type;
70 };
71 template<typename T>
72 struct get_type<boost::weak_ptr<T> > {
73         typedef typename get_type<T>::type type;
74 };
75 template<typename T>
76 struct get_type<boost::intrusive_ptr<T> > {
77         typedef typename get_type<T>::type type;
78 };
79
80 } // end namespace detail
81
82 /**
83  * Unchains any pointer (even smart and nested) type, and returns a reference
84  * to the real type. Const-correctness is preserved, thus passing a pointer to
85  * const object and expecting non-const reference in return is an error.
86  *
87  * @param ptr        Pointer expected to be unchained. Non-pointers are returned
88  *                   unmodified.
89  * @returns          Class& or const Class&, depending on input parameters.
90  */
91 template<typename ChainedPtr>
92 inline typename detail::get_type<ChainedPtr>::type&
93 unchain_ptr(ChainedPtr ptr) {
94         return typename boost::mpl::if_<
95                 boost::is_const<ChainedPtr>,
96                 detail::unchainptr_const_impl<
97                         typename detail::get_type<ChainedPtr>::type
98                 >,
99                 detail::unchainptr_impl<
100                         typename detail::get_type<ChainedPtr>::type
101                 >
102         >::type()(ptr);
103 }
104
105 } // end namespace Utils
106
107 #endif
Note: See TracBrowser for help on using the browser.