00001
00002 #ifndef INSTIGATE_STL_TEMPORARY_BUFFER_HPP
00003 #define INSTIGATE_STL_TEMPORARY_BUFFER_HPP
00004
00050
00051 #include "_distance.hpp"
00052 #include "_destructible_iterator.hpp"
00053
00054
00055
00056
00057 #include <iostream>
00058 #include <limits.h>
00059
00060
00061 namespace instigate {
00062 namespace stl {
00063 namespace implementation {
00064 template <typename ForwardIterator, typename Tp>
00065 class Temporary_buffer;
00066 }
00067 }
00068 }
00069
00071 template <typename ForwardIterator, typename Tp>
00072 class instigate::stl::implementation::Temporary_buffer
00073 {
00074 private:
00075 ptrdiff_t m_original_len;
00076 ptrdiff_t m_len;
00077 Tp* m_buffer;
00078
00079 void m_allocate_buffer()
00080 {
00081 m_original_len = m_len;
00082 m_buffer = 0;
00083 if (m_len > (ptrdiff_t)(INT_MAX / sizeof(Tp))) {
00084 m_len = INT_MAX / sizeof(Tp);
00085 }
00086 while (m_len > 0) {
00087 m_buffer = new Tp[m_len * sizeof(Tp)];
00088 if (0 != m_buffer) {
00089 break;
00090 }
00091 m_len /= 2;
00092 }
00093 }
00094
00095 void m_initialize_buffer(const Tp&, true_type) {}
00096
00097 void m_initialize_buffer(const Tp& val, false_type)
00098 {
00099 uninitialized_fill_n(m_buffer, m_len, val);
00100 }
00101
00102 public:
00104 ptrdiff_t size() const { return m_len; }
00105
00107 ptrdiff_t requested_size() const { return m_original_len; }
00108
00110 Tp* begin() { return m_buffer; }
00111
00113 Tp* end() { return m_buffer + m_len; }
00114
00120 Temporary_buffer(ForwardIterator first, ForwardIterator last) {
00121 #if defined(__sgi) && !defined(__GNUC__) && _COMPILER_VERSION < 730
00122 typedef typename unary_type_traits<Tp>::is_POD_type _Trivial;
00123 #else
00124 typedef typename unary_type_traits<Tp>::has_trivial_default_constructor Trivial;
00125 #endif
00126 m_len = 0;
00127 m_len = instigate::stl::distance(first, last);
00128 m_allocate_buffer();
00129 if (m_len > 0) {
00130 m_initialize_buffer(*first, Trivial());
00131 }
00132 }
00133
00135 ~Temporary_buffer()
00136 {
00137 instigate::stl::destructible_iterator::interface<Tp*>::
00138 destroy(m_buffer, m_buffer + m_len);
00139 free(m_buffer);
00140 }
00141
00142 private:
00143
00144 Temporary_buffer(const Temporary_buffer&) {}
00145 void operator=(const Temporary_buffer&) {}
00146 };
00147
00148
00149
00150 #endif // INSTIGATE_STL_TEMPORARY_BUFFER_HPP