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: any_iterator_buffer()26 any_iterator_buffer() 27 : m_ptr() 28 { 29 } 30 ~any_iterator_buffer()31 ~any_iterator_buffer() 32 { 33 delete [] m_ptr; 34 } 35 allocate(std::size_t bytes)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 deallocate()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: any_iterator_heap_only_buffer()68 any_iterator_heap_only_buffer() 69 : m_ptr() 70 { 71 } 72 ~any_iterator_heap_only_buffer()73 ~any_iterator_heap_only_buffer() 74 { 75 delete [] m_ptr; 76 } 77 allocate(std::size_t bytes)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 deallocate()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: allocate(std::size_t bytes)100 void* allocate(std::size_t bytes) 101 { 102 BOOST_ASSERT( bytes <= m_buffer.size() ); 103 return m_buffer.data(); 104 } 105 deallocate()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