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
18namespace 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