| 1 |
#ifndef CBEAR_BERLIOS_DE_RANGE_HELPER_HPP_INCLUDED |
|---|
| 2 |
#define CBEAR_BERLIOS_DE_RANGE_HELPER_HPP_INCLUDED |
|---|
| 3 |
|
|---|
| 4 |
#include <cbear.berlios.de/cast/default.hpp> |
|---|
| 5 |
#include <cbear.berlios.de/base/empty.hpp> |
|---|
| 6 |
#include <cbear.berlios.de/base/integer.hpp> |
|---|
| 7 |
|
|---|
| 8 |
|
|---|
| 9 |
#include <iterator> |
|---|
| 10 |
|
|---|
| 11 |
|
|---|
| 12 |
#include <boost/utility.hpp> |
|---|
| 13 |
|
|---|
| 14 |
#include <boost/type_traits/is_same.hpp> |
|---|
| 15 |
|
|---|
| 16 |
namespace cbear_berlios_de |
|---|
| 17 |
{ |
|---|
| 18 |
namespace range |
|---|
| 19 |
{ |
|---|
| 20 |
|
|---|
| 21 |
template<class Iterator> |
|---|
| 22 |
class iterator_range; |
|---|
| 23 |
|
|---|
| 24 |
template<class Container, class Base> |
|---|
| 25 |
class helper_t: public Base |
|---|
| 26 |
{ |
|---|
| 27 |
public: |
|---|
| 28 |
typedef Container container_t; |
|---|
| 29 |
typedef typename Base::iterator iterator; |
|---|
| 30 |
typedef typename Base::const_iterator const_iterator; |
|---|
| 31 |
|
|---|
| 32 |
typedef ::std::iterator_traits<iterator> iterator_traits; |
|---|
| 33 |
typedef ::std::iterator_traits<const_iterator> const_iterator_traits; |
|---|
| 34 |
|
|---|
| 35 |
typedef typename const_iterator_traits::value_type value_type; |
|---|
| 36 |
typedef typename const_iterator_traits::difference_type difference_type; |
|---|
| 37 |
typedef typename base::make_unsigned<difference_type>::type size_type; |
|---|
| 38 |
|
|---|
| 39 |
typedef typename iterator_traits::reference reference; |
|---|
| 40 |
typedef typename const_iterator_traits::reference const_reference; |
|---|
| 41 |
typedef typename iterator_traits::pointer pointer; |
|---|
| 42 |
typedef typename const_iterator_traits::pointer const_pointer; |
|---|
| 43 |
|
|---|
| 44 |
typedef typename ::std::reverse_iterator<iterator> |
|---|
| 45 |
reverse_iterator; |
|---|
| 46 |
typedef typename ::std::reverse_iterator<const_iterator> |
|---|
| 47 |
const_reverse_iterator; |
|---|
| 48 |
|
|---|
| 49 |
typedef iterator_range<iterator> iterator_range_t; |
|---|
| 50 |
typedef iterator_range<const_iterator> const_iterator_range_t; |
|---|
| 51 |
|
|---|
| 52 |
helper_t() |
|---|
| 53 |
{ |
|---|
| 54 |
} |
|---|
| 55 |
|
|---|
| 56 |
template<class T> |
|---|
| 57 |
helper_t(T const &X): |
|---|
| 58 |
Base(X) |
|---|
| 59 |
{ |
|---|
| 60 |
} |
|---|
| 61 |
|
|---|
| 62 |
template<class T1, class T2> |
|---|
| 63 |
helper_t(T1 const &X1, T2 const &X2): |
|---|
| 64 |
Base(X1, X2) |
|---|
| 65 |
{ |
|---|
| 66 |
} |
|---|
| 67 |
|
|---|
| 68 |
bool empty() const |
|---|
| 69 |
{ |
|---|
| 70 |
return this->This().begin()==this->This().end(); |
|---|
| 71 |
} |
|---|
| 72 |
size_type size() const |
|---|
| 73 |
{ |
|---|
| 74 |
return size_type(::std::distance( |
|---|
| 75 |
this->This().begin(), this->This().end())); |
|---|
| 76 |
} |
|---|
| 77 |
|
|---|
| 78 |
reference front() |
|---|
| 79 |
{ |
|---|
| 80 |
return *This().begin(); |
|---|
| 81 |
} |
|---|
| 82 |
const_reference front() const |
|---|
| 83 |
{ |
|---|
| 84 |
return *This().begin(); |
|---|
| 85 |
} |
|---|
| 86 |
reference back() |
|---|
| 87 |
{ |
|---|
| 88 |
return *boost::prior(This().end()); |
|---|
| 89 |
} |
|---|
| 90 |
const_reference back() const |
|---|
| 91 |
{ |
|---|
| 92 |
return *boost::prior(This().end()); |
|---|
| 93 |
} |
|---|
| 94 |
reference at(size_type I) |
|---|
| 95 |
{ |
|---|
| 96 |
return *boost::next(this->This().begin(), I); |
|---|
| 97 |
} |
|---|
| 98 |
const_reference at(size_type I) const |
|---|
| 99 |
{ |
|---|
| 100 |
return *boost::next(this->This().begin(), I); |
|---|
| 101 |
} |
|---|
| 102 |
reference operator[](size_type I) |
|---|
| 103 |
{ |
|---|
| 104 |
return this->at(I); |
|---|
| 105 |
} |
|---|
| 106 |
const_reference operator[](size_type I) const |
|---|
| 107 |
{ |
|---|
| 108 |
return this->at(I); |
|---|
| 109 |
} |
|---|
| 110 |
|
|---|
| 111 |
reverse_iterator rbegin() |
|---|
| 112 |
{ |
|---|
| 113 |
return reverse_iterator(This().end()); |
|---|
| 114 |
} |
|---|
| 115 |
const_reverse_iterator rbegin() const |
|---|
| 116 |
{ |
|---|
| 117 |
return const_reverse_iterator(This().end()); |
|---|
| 118 |
} |
|---|
| 119 |
|
|---|
| 120 |
reverse_iterator rend() |
|---|
| 121 |
{ |
|---|
| 122 |
return reverse_iterator(This().begin()); |
|---|
| 123 |
} |
|---|
| 124 |
const_reverse_iterator rend() const |
|---|
| 125 |
{ |
|---|
| 126 |
return const_reverse_iterator(This().begin()); |
|---|
| 127 |
} |
|---|
| 128 |
|
|---|
| 129 |
template<class Stream> |
|---|
| 130 |
void write(Stream &S) const |
|---|
| 131 |
{ |
|---|
| 132 |
typedef typename Stream::value_type char_t; |
|---|
| 133 |
BOOST_STATIC_ASSERT((boost::is_same<char_t, value_type>::value)); |
|---|
| 134 |
S.push_back_range(this->This()); |
|---|
| 135 |
} |
|---|
| 136 |
|
|---|
| 137 |
void resize(size_type S) |
|---|
| 138 |
{ |
|---|
| 139 |
difference_type dif = |
|---|
| 140 |
static_cast<difference_type>(S) - |
|---|
| 141 |
static_cast<difference_type>(this->This().size()); |
|---|
| 142 |
if(dif > 0) |
|---|
| 143 |
{ |
|---|
| 144 |
this->This().insert_range(this->This().end(), make_fill(base::default_(), dif)); |
|---|
| 145 |
} |
|---|
| 146 |
else if(dif < 0) |
|---|
| 147 |
{ |
|---|
| 148 |
this->This().erase_range(iterator_range_t( |
|---|
| 149 |
::boost::prior(this->This().end(), -dif), this->This().end())); |
|---|
| 150 |
} |
|---|
| 151 |
} |
|---|
| 152 |
|
|---|
| 153 |
template<class T> |
|---|
| 154 |
iterator insert(iterator I, T const &X) |
|---|
| 155 |
{ |
|---|
| 156 |
return this->This().insert_range(I, make_fill(X, 1)); |
|---|
| 157 |
} |
|---|
| 158 |
template<class T> |
|---|
| 159 |
void push_front(T const &X) |
|---|
| 160 |
{ |
|---|
| 161 |
this->insert(this->This().begin(), X); |
|---|
| 162 |
} |
|---|
| 163 |
void push_front() |
|---|
| 164 |
{ |
|---|
| 165 |
this->insert(this->This().begin(), base::default_()); |
|---|
| 166 |
} |
|---|
| 167 |
template<class R> |
|---|
| 168 |
void push_front_range(R const &source) |
|---|
| 169 |
{ |
|---|
| 170 |
this->This().insert_range(this->This().begin(), source); |
|---|
| 171 |
} |
|---|
| 172 |
template<class T> |
|---|
| 173 |
void push_back(T const &X) |
|---|
| 174 |
{ |
|---|
| 175 |
this->insert(this->This().end(), X); |
|---|
| 176 |
} |
|---|
| 177 |
void push_back() |
|---|
| 178 |
{ |
|---|
| 179 |
this->insert(this->This().end(), base::default_()); |
|---|
| 180 |
} |
|---|
| 181 |
template<class R> |
|---|
| 182 |
void push_back_range(R const &source) |
|---|
| 183 |
{ |
|---|
| 184 |
this->This().insert_range(this->This().end(), source); |
|---|
| 185 |
} |
|---|
| 186 |
|
|---|
| 187 |
void erase(iterator I) |
|---|
| 188 |
{ |
|---|
| 189 |
this->This().erase_range(iterator_range_t(I, 1)); |
|---|
| 190 |
} |
|---|
| 191 |
|
|---|
| 192 |
private: |
|---|
| 193 |
container_t &This() |
|---|
| 194 |
{ |
|---|
| 195 |
return *static_cast<container_t *>(this); |
|---|
| 196 |
} |
|---|
| 197 |
container_t const &This() const |
|---|
| 198 |
{ |
|---|
| 199 |
return *static_cast<container_t const *>(this); |
|---|
| 200 |
} |
|---|
| 201 |
}; |
|---|
| 202 |
|
|---|
| 203 |
} |
|---|
| 204 |
} |
|---|
| 205 |
|
|---|
| 206 |
#endif |
|---|
| 207 |
|
|---|