source: NonGTP/Boost/boost/detail/sp_counted_impl.hpp @ 857

Revision 857, 4.2 KB checked in by igarcia, 18 years ago (diff)
Line 
1#ifndef BOOST_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
2#define BOOST_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
3
4// MS compatible compilers support #pragma once
5
6#if defined(_MSC_VER) && (_MSC_VER >= 1020)
7# pragma once
8#endif
9
10//
11//  detail/sp_counted_impl.hpp
12//
13//  Copyright (c) 2001, 2002, 2003 Peter Dimov and Multi Media Ltd.
14//  Copyright 2004-2005 Peter Dimov
15//
16// Distributed under the Boost Software License, Version 1.0. (See
17// accompanying file LICENSE_1_0.txt or copy at
18// http://www.boost.org/LICENSE_1_0.txt)
19//
20
21#include <boost/config.hpp>
22
23#if defined(BOOST_SP_USE_STD_ALLOCATOR) && defined(BOOST_SP_USE_QUICK_ALLOCATOR)
24# error BOOST_SP_USE_STD_ALLOCATOR and BOOST_SP_USE_QUICK_ALLOCATOR are incompatible.
25#endif
26
27#include <boost/checked_delete.hpp>
28#include <boost/detail/sp_counted_base.hpp>
29
30#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
31#include <boost/detail/quick_allocator.hpp>
32#endif
33
34#include <memory>           // std::allocator
35#include <typeinfo>         // std::type_info in get_deleter
36#include <cstddef>          // std::size_t
37
38namespace boost
39{
40
41#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
42
43void sp_scalar_constructor_hook( void * px, std::size_t size, void * pn );
44void sp_scalar_destructor_hook( void * px, std::size_t size, void * pn );
45
46#endif
47
48namespace detail
49{
50
51template<class X> class sp_counted_impl_p: public sp_counted_base
52{
53private:
54
55    X * px_;
56
57    sp_counted_impl_p( sp_counted_impl_p const & );
58    sp_counted_impl_p & operator= ( sp_counted_impl_p const & );
59
60    typedef sp_counted_impl_p<X> this_type;
61
62public:
63
64    explicit sp_counted_impl_p( X * px ): px_( px )
65    {
66#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
67        boost::sp_scalar_constructor_hook( px, sizeof(X), this );
68#endif
69    }
70
71    virtual void dispose() // nothrow
72    {
73#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
74        boost::sp_scalar_destructor_hook( px_, sizeof(X), this );
75#endif
76        boost::checked_delete( px_ );
77    }
78
79    virtual void * get_deleter( std::type_info const & )
80    {
81        return 0;
82    }
83
84#if defined(BOOST_SP_USE_STD_ALLOCATOR)
85
86    void * operator new( std::size_t )
87    {
88        return std::allocator<this_type>().allocate( 1, static_cast<this_type *>(0) );
89    }
90
91    void operator delete( void * p )
92    {
93        std::allocator<this_type>().deallocate( static_cast<this_type *>(p), 1 );
94    }
95
96#endif
97
98#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
99
100    void * operator new( std::size_t )
101    {
102        return quick_allocator<this_type>::alloc();
103    }
104
105    void operator delete( void * p )
106    {
107        quick_allocator<this_type>::dealloc( p );
108    }
109
110#endif
111};
112
113//
114// Borland's Codeguard trips up over the -Vx- option here:
115//
116#ifdef __CODEGUARD__
117# pragma option push -Vx-
118#endif
119
120template<class P, class D> class sp_counted_impl_pd: public sp_counted_base
121{
122private:
123
124    P ptr; // copy constructor must not throw
125    D del; // copy constructor must not throw
126
127    sp_counted_impl_pd( sp_counted_impl_pd const & );
128    sp_counted_impl_pd & operator= ( sp_counted_impl_pd const & );
129
130    typedef sp_counted_impl_pd<P, D> this_type;
131
132public:
133
134    // pre: d(p) must not throw
135
136    sp_counted_impl_pd( P p, D d ): ptr(p), del(d)
137    {
138    }
139
140    virtual void dispose() // nothrow
141    {
142        del( ptr );
143    }
144
145    virtual void * get_deleter( std::type_info const & ti )
146    {
147        return ti == typeid(D)? &del: 0;
148    }
149
150#if defined(BOOST_SP_USE_STD_ALLOCATOR)
151
152    void * operator new( std::size_t )
153    {
154        return std::allocator<this_type>().allocate( 1, static_cast<this_type *>(0) );
155    }
156
157    void operator delete( void * p )
158    {
159        std::allocator<this_type>().deallocate( static_cast<this_type *>(p), 1 );
160    }
161
162#endif
163
164#if defined(BOOST_SP_USE_QUICK_ALLOCATOR)
165
166    void * operator new( std::size_t )
167    {
168        return quick_allocator<this_type>::alloc();
169    }
170
171    void operator delete( void * p )
172    {
173        quick_allocator<this_type>::dealloc( p );
174    }
175
176#endif
177};
178
179#ifdef __CODEGUARD__
180# pragma option pop
181#endif
182
183} // namespace detail
184
185} // namespace boost
186
187#endif  // #ifndef BOOST_DETAIL_SP_COUNTED_IMPL_HPP_INCLUDED
Note: See TracBrowser for help on using the repository browser.