74 #ifndef SLIP_PYRAMID_HPP
75 #define SLIP_PYRAMID_HPP
83 #include <boost/serialization/access.hpp>
84 #include <boost/serialization/split_member.hpp>
85 #include <boost/serialization/string.hpp>
86 #include <boost/serialization/complex.hpp>
87 #include <boost/serialization/vector.hpp>
88 #include <boost/serialization/version.hpp>
94 template<
typename Container,
typename>
95 struct __container_size
97 template <
typename _II>
99 container_size(_II first, _II last)
101 return static_cast<std::size_t
>(last-first);
106 template<
typename Container>
107 struct __container_size<Container,std::random_access_iterator_tag>
109 template <
typename _II>
111 container_size(_II first, _II last)
113 return static_cast<std::size_t
>(last-first);
117 template<
typename Container>
118 struct __container_size<Container,std::random_access_iterator2d_tag>
120 template <
typename _II>
122 container_size(_II first, _II last)
124 return static_cast<std::size_t
>(((last-first)[0])*((last-first)[1]));
128 template<
typename Container>
129 struct __container_size<Container,std::random_access_iterator3d_tag>
131 template <
typename _II>
133 container_size(_II first, _II last)
135 return static_cast<std::size_t
>(((last-first)[0])*((last-first)[1])*((last-first)[2]));
141 template<
typename Container>
146 template<
typename Iterator>
149 typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
150 return __container_size<Container,_Category>::container_size(first,last);
157 template<
typename Container,
typename>
158 struct __container_resolution
160 template <
typename _II>
162 container_resolution(_II first, _II last)
165 R[0] =
static_cast<std::size_t
>(last-first);
171 template<
typename Container>
172 struct __container_resolution<Container,std::random_access_iterator_tag>
174 template <
typename _II>
176 container_resolution(_II first, _II last)
179 R[0] =
static_cast<std::size_t
>(last-first);
184 template<
typename Container>
185 struct __container_resolution<Container,std::random_access_iterator2d_tag>
187 template <
typename _II>
189 container_resolution(_II first, _II last)
192 R[0] =
static_cast<std::size_t
>((last-first)[0]);
193 R[1] =
static_cast<std::size_t
>((last-first)[1]);
198 template<
typename Container>
199 struct __container_resolution<Container,std::random_access_iterator3d_tag>
201 template <
typename _II>
203 container_resolution(_II first, _II last)
206 R[0] =
static_cast<std::size_t
>((last-first)[0]);
207 R[1] =
static_cast<std::size_t
>((last-first)[1]);
208 R[2] =
static_cast<std::size_t
>((last-first)[2]);
216 template<
typename Container>
221 template<
typename Iterator>
224 typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
225 return __container_resolution<Container,_Category>::container_resolution(first,last);
235 template<
typename Container,
typename>
236 struct __container_allocator
241 return new Container(res[0]);
246 template<
typename Container>
247 struct __container_allocator<Container,std::random_access_iterator_tag>
253 return new Container(res[0]);
258 template<
typename Container>
259 struct __container_allocator<Container,std::random_access_iterator2d_tag>
264 return new Container(res[0],res[1]);
269 template<
typename Container>
270 struct __container_allocator<Container,std::random_access_iterator3d_tag>
275 return new Container(res[0],res[1],res[2]);
280 template<
typename Container>
287 typedef typename std::iterator_traits<typename Container::default_iterator>::iterator_category _Category;
288 return __container_allocator<Container,_Category>::container_allocator(res);
295 template<
typename Container,
typename>
296 struct __pyramid_allocator
298 template <
typename _II>
299 static std::vector<Container*>*
300 pyramid_allocator(_II first, _II last,
const std::size_t levels)
303 assert(
slip::power(2,levels-1) <=
int(last-first));
304 std::size_t lenght =
static_cast<std::size_t
>(last-first);
307 std::vector<Container*>* data_ =
new std::vector<Container*>(levels);
308 (*data_)[0] =
new Container(lenght);
309 std::copy(first,last,((*data_)[0])->begin());
310 for(std::size_t i = 1; i < levels; ++i)
312 (*data_)[i] =
new Container((*data_)[i-1]->size()/2);
319 template<
typename Container>
320 struct __pyramid_allocator<Container,std::random_access_iterator_tag>
322 template <
typename _II>
323 static std::vector<Container*>*
324 pyramid_allocator(_II first, _II last,
const std::size_t levels)
327 assert(
slip::power(2,levels-1) <=
int(last-first));
328 std::size_t lenght =
static_cast<std::size_t
>(last-first);
331 std::vector<Container*>* data_ =
new std::vector<Container*>(levels);
332 (*data_)[0] =
new Container(lenght);
333 std::copy(first,last,((*data_)[0])->begin());
334 for(std::size_t i = 1; i < levels; ++i)
336 (*data_)[i] =
new Container((*data_)[i-1]->size()/2);
342 template<
typename Container>
343 struct __pyramid_allocator<Container,std::random_access_iterator2d_tag>
345 template <
typename _II>
346 static std::vector<Container*>*
347 pyramid_allocator(_II first, _II last,
const std::size_t levels)
350 assert(
slip::power(2,levels-1) <=
int((last-first)[0]));
351 assert(
slip::power(2,levels-1) <=
int((last-first)[1]));
352 std::size_t rows =
static_cast<std::size_t
>((last-first)[0]);
353 std::size_t cols =
static_cast<std::size_t
>((last-first)[1]);
356 std::vector<Container*>* data_ =
new std::vector<Container*>(levels);
357 (*data_)[0] =
new Container(rows,cols);
358 std::copy(first,last,((*data_)[0])->begin());
359 for(std::size_t i = 1; i < levels; ++i)
361 (*data_)[i] =
new Container((*data_)[i-1]->rows()/2,(*data_)[i-1]->cols()/2);
367 template<
typename Container>
368 struct __pyramid_allocator<Container,std::random_access_iterator3d_tag>
370 template <
typename _II>
371 static std::vector<Container*>*
372 pyramid_allocator(_II first, _II last,
const std::size_t levels)
375 assert(
slip::power(2,levels-1) <=
int((last-first)[0]));
376 assert(
slip::power(2,levels-1) <=
int((last-first)[1]));
377 assert(
slip::power(2,levels-1) <=
int((last-first)[2]));
379 std::size_t slices =
static_cast<std::size_t
>((last-first)[0]);
380 std::size_t rows =
static_cast<std::size_t
>((last-first)[1]);
381 std::size_t cols =
static_cast<std::size_t
>((last-first)[2]);
384 std::vector<Container*>* data_ =
new std::vector<Container*>(levels);
385 (*data_)[0] =
new Container(slices,rows,cols);
386 std::copy(first,last,((*data_)[0])->begin());
387 for(std::size_t i = 1; i < levels; ++i)
389 (*data_)[i] =
new Container((*data_)[i-1]->slices()/2,
390 (*data_)[i-1]->rows()/2,
391 (*data_)[i-1]->cols()/2);
399 template<
typename Container>
404 template<
typename Iterator>
405 std::vector<Container*>*
operator() (Iterator first, Iterator last,
const std::size_t levels)
const
407 typedef typename std::iterator_traits<Iterator>::iterator_category _Category;
408 return __pyramid_allocator<Container,_Category>::pyramid_allocator(first,last,levels);
415 template<
typename Container,
typename>
416 struct __pyramid_copy
418 static std::vector<Container*>*
419 pyramid_copy(
const Container& c,
const std::size_t levels)
422 typedef typename std::iterator_traits<typename Container::default_iterator>::iterator_category _Category;
423 return __pyramid_allocator<Container,_Category>::pyramid_allocator(c.begin(),c.end(),levels);
428 template<
typename Container>
429 struct __pyramid_copy<Container,std::random_access_iterator_tag>
431 static std::vector<Container*>*
432 pyramid_copy(
const Container& c,
const std::size_t levels)
435 typedef typename std::iterator_traits<typename Container::default_iterator>::iterator_category _Category;
436 return __pyramid_allocator<Container,_Category>::pyramid_allocator(c.begin(),c.end(),levels);
440 template<
typename Container>
441 struct __pyramid_copy<Container,std::random_access_iterator2d_tag>
443 static std::vector<Container*>*
444 pyramid_copy(
const Container& c,
const std::size_t levels)
447 typedef typename std::iterator_traits<typename Container::default_iterator>::iterator_category _Category;
448 return __pyramid_allocator<Container,_Category>::pyramid_allocator(c.upper_left(),c.bottom_right(),levels);
452 template<
typename Container>
453 struct __pyramid_copy<Container,std::random_access_iterator3d_tag>
455 static std::vector<Container*>*
456 pyramid_copy(
const Container& c,
const std::size_t levels)
459 typedef typename std::iterator_traits<typename Container::default_iterator>::iterator_category _Category;
460 return __pyramid_allocator<Container,_Category>::pyramid_allocator(c.front_upper_left(),c.back_bottom_right(),levels);
466 template<
typename Container>
472 const std::size_t levels)
const
475 typedef typename std::iterator_traits<typename Container::default_iterator>::iterator_category _Category;
476 return __pyramid_copy<Container,_Category>::pyramid_copy(c,levels);
484 template <
typename Container>
487 template <
typename Container>
488 std::ostream& operator<<(std::ostream & out, const slip::Pyramid<Container>& a);
490 template<
typename Container>
494 template<
typename Container>
510 template <
class Container>
542 base_size_(slip::
Array<std::size_t>())
566 template<
typename Iterator>
568 Iterator init_container_last,
575 init_container_last))
598 data_(slip::
Pyramid_Copy<Container>()(*((*(rhs.data_))[0]),rhs.levels_)),
599 levels_(rhs.levels_),
604 for(std::size_t i = 0; i < this->levels_; ++i)
606 std::copy(rhs[i].begin(),rhs[i].end(),((*data_)[i])->begin());
635 if((this->levels_ != rhs.levels_) ||
636 (((*data_)[0])->size() != ((*(rhs.data_))[0])->
size()))
639 this->levels_ = rhs.levels_;
640 this->base_size_ = rhs.base_size();
644 for(std::size_t i = 0; i < this->levels_; ++i)
646 std::copy(rhs[i].begin(),rhs[i].end(),((*data_)[i])->begin());
662 return this->levels_;
667 return this->base_size_;
689 assert(n < this->
levels());
690 return *((*data_)[n]);
707 assert(n < this->
levels());
708 return *((*data_)[n]);
721 friend std::ostream& operator<< <>(std::ostream & out,
731 return data_->size();
738 return data_->max_size();
746 return data_->empty();
755 assert((this->levels_ == rhs.levels_) && (((*data_)[0])->size() == ((*(rhs.data_))[0])->
size()));
756 for(std::size_t i = 0; i < this->levels_; ++i)
758 (*(*rhs.data_)[i]).swap(*((*data_)[i]));
766 void fill(
const typename Container::value_type& val)
768 for(std::size_t i = 0; i < this->levels_; ++i)
770 std::fill(((*data_)[i])->begin(),((*data_)[i])->end(),val);
799 std::vector<Container* >* data_;
808 for(std::size_t i = 0; i < this->levels_; ++i)
820 template<
class Archive>
821 void save(Archive & ar,
const unsigned int version)
const
824 ar & this->base_size_;
826 for(std::size_t l = 0; l < this->levels_;++l)
832 template<
class Archive>
833 void load(Archive & ar,
const unsigned int version)
838 ar & this->base_size_;
842 std::cout<<
"this->base_size_ "<<this->base_size_<<std::endl;
844 typename Container::default_iterator first;
845 typename Container::default_iterator last;
847 std::cout<<
"last-first = "<<(last-first)<<std::endl;
851 for(std::size_t l = 0; l < this->levels_;++l)
857 BOOST_SERIALIZATION_SPLIT_MEMBER();
866 template <
typename Container>
868 std::ostream& operator<<(std::ostream & out, const slip::Pyramid<Container>& a)
870 out<<
"Pyramid levels : "<<a.levels_<<std::endl;
871 out<<
"Pyramid base size : "<<a.base_size_<<std::endl;
872 for(std::size_t i = 0; i < a.levels_; ++i)
874 out<<
"Level "<<i<<std::endl;
875 out<<*((*a.data_)[i])<<std::endl;
884 template<
typename Container>
894 const size_type size = x.
size();
895 for (size_type i = 0; i < size; ++i)
905 template<
typename Container>
914 #endif // SLIP_PYRAMID_HPP
void container_cast(Container &cont, _II &first, _II &last)
Get the default iterators of a SLIP container.
bool operator!=(const Array< T > &x, const Array< T > &y)
friend class boost::serialization::access
const slip::Array< size_type > & base_size() const
const_pointer const_iterator
Pyramid()
Constructs a Pyramid with no data and zero levels.
self & operator=(const self &rhs)
Assigns rhs to the Pyramid.
T power(T x, Integer N)
function to compute.
~Pyramid()
Destructor of the Pyramid.
Pyramid(Iterator init_container_first, Iterator init_container_last, const size_type levels)
Constructs a Pyramid of levels level and copy the finest level (0 level) with the range [init_contain...
void fill(const typename Container::value_type &val)
Fill all the container of the Pyramid with val.
value_type const * const_pointer
ptrdiff_t difference_type
bool empty() const
Returns true if the Pyramid is empty. (Thus size() == 0)
void swap(self &rhs)
Swaps data with another Pyramid.
Container * operator()(const slip::Array< std::size_t > &res) const
const_reference operator[](const size_type n) const
Subscript access to the data contained in the Pyramid.
This is container to handle a pyramid of containers.
Provides a class to manipulate 1d dynamic and generic arrays.
reference operator[](const size_type n)
Subscript access to the data contained in the Pyramid.
std::vector< Container * > * operator()(Iterator first, Iterator last, const std::size_t levels) const
Provides some statistics algorithms.
void copy(_II first, _II last, _OI output_first)
Copy algorithm optimized for slip iterators.
value_type const & const_reference
std::size_t operator()(Iterator first, Iterator last) const
std::vector< Container * > * operator()(const Container &c, const std::size_t levels) const
size_type size() const
Returns the number of containers in the Pyramid.
size_type max_size() const
Returns the maximal size (number of container) in the Pyramid.
bool operator==(const Array< T > &x, const Array< T > &y)
Pyramid(const self &rhs)
Constructs a copy of the Pyramid rhs.
slip::Array< std::size_t > operator()(Iterator first, Iterator last) const
Provides some algorithms to get the default iterators associated with containers. ...
const Pyramid< Container > const_self