1 | // Boost.Range library |
---|---|
2 | // |
3 | // Copyright Neil Groves 2010. Use, modification and |
4 | // distribution is subject to the Boost Software License, Version |
5 | // 1.0. (See accompanying file LICENSE_1_0.txt or copy at |
6 | // http://www.boost.org/LICENSE_1_0.txt) |
7 | // |
8 | // For more information, see http://www.boost.org/libs/range/ |
9 | // |
10 | #ifndef BOOST_RANGE_DETAIL_ANY_ITERATOR_BUFFER_HPP_INCLUDED |
11 | #define BOOST_RANGE_DETAIL_ANY_ITERATOR_BUFFER_HPP_INCLUDED |
12 | |
13 | #include <boost/array.hpp> |
14 | #include <boost/assert.hpp> |
15 | #include <boost/static_assert.hpp> |
16 | #include <boost/noncopyable.hpp> |
17 | |
18 | namespace boost |
19 | { |
20 | template<std::size_t StackBufferSize> |
21 | class any_iterator_buffer |
22 | : noncopyable |
23 | { |
24 | BOOST_STATIC_ASSERT(( StackBufferSize > 0 )); |
25 | public: |
26 | any_iterator_buffer() |
27 | : m_ptr() |
28 | { |
29 | } |
30 | |
31 | ~any_iterator_buffer() |
32 | { |
33 | delete [] m_ptr; |
34 | } |
35 | |
36 | void* allocate(std::size_t bytes) |
37 | { |
38 | BOOST_ASSERT( !m_ptr ); |
39 | if (bytes <= StackBufferSize) |
40 | return m_buffer.data(); |
41 | |
42 | m_ptr = new char[bytes]; |
43 | return m_ptr; |
44 | } |
45 | |
46 | void deallocate() |
47 | { |
48 | delete [] m_ptr; |
49 | m_ptr = 0; |
50 | } |
51 | |
52 | private: |
53 | // Rationale: |
54 | // Do not use inheritance from noncopyable because this causes |
55 | // the concepts to erroneous detect the derived any_iterator |
56 | // as noncopyable. |
57 | any_iterator_buffer(const any_iterator_buffer&); |
58 | void operator=(const any_iterator_buffer&); |
59 | |
60 | char* m_ptr; |
61 | boost::array<char, StackBufferSize> m_buffer; |
62 | }; |
63 | |
64 | class any_iterator_heap_only_buffer |
65 | : noncopyable |
66 | { |
67 | public: |
68 | any_iterator_heap_only_buffer() |
69 | : m_ptr() |
70 | { |
71 | } |
72 | |
73 | ~any_iterator_heap_only_buffer() |
74 | { |
75 | delete [] m_ptr; |
76 | } |
77 | |
78 | void* allocate(std::size_t bytes) |
79 | { |
80 | BOOST_ASSERT( !m_ptr ); |
81 | m_ptr = new char[bytes]; |
82 | return m_ptr; |
83 | } |
84 | |
85 | void deallocate() |
86 | { |
87 | delete [] m_ptr; |
88 | m_ptr = 0; |
89 | } |
90 | |
91 | private: |
92 | char* m_ptr; |
93 | }; |
94 | |
95 | template<std::size_t StackBufferSize> |
96 | class any_iterator_stack_only_buffer |
97 | { |
98 | BOOST_STATIC_ASSERT(( StackBufferSize > 0 )); |
99 | public: |
100 | void* allocate(std::size_t bytes) |
101 | { |
102 | BOOST_ASSERT( bytes <= m_buffer.size() ); |
103 | return m_buffer.data(); |
104 | } |
105 | |
106 | void deallocate() |
107 | { |
108 | } |
109 | |
110 | private: |
111 | boost::array<char, StackBufferSize> m_buffer; |
112 | }; |
113 | |
114 | typedef any_iterator_buffer<64> any_iterator_default_buffer; |
115 | } // namespace boost |
116 | |
117 | #endif // include guard |
118 |