19 #ifndef __TPIE_ARRAY_H__
20 #define __TPIE_ARRAY_H__
27 #include <boost/iterator/iterator_facade.hpp>
30 #include <type_traits>
40 template <
typename TT,
bool forward>
42 array_iter_base<TT, forward>,
43 TT , boost::random_access_traversal_tag> {
45 template <
typename,
typename>
friend class array;
46 friend class boost::iterator_core_access;
51 TT & dereference()
const {
return * elm;}
54 void increment() {elm += forward?1:-1;}
55 void decrement() {elm += forward?-1:1;}
56 void advance(
size_t n) {
if (forward) elm += n;
else elm -= n;}
57 ptrdiff_t distance_to(
array_iter_base const & o)
const {
return (forward?1:-1) * (o.elm - elm);}
66 TT & operator[](ptrdiff_t n)
const noexcept {
67 return *(forward?elm+n:elm-n);
77 typename std::enable_if<
78 std::is_convertible<U*,TT*>::value>::type* = 0)
148 template <
typename T,
typename Allocator = allocator<T> >
173 assert(idx <=
size());
174 return get_iter(idx);
184 assert(idx <=
size());
185 return get_iter(idx);
193 T &
at(
size_t i)
throw() {
195 return m_elements[i];
201 const T &
at(
size_t i)
const throw() {
203 return m_elements[i];
216 for (
size_t i=0; i <
size(); ++i) m_elements[i] = other[i];
230 std::swap(m_allocator, other.m_allocator);
231 std::swap(m_elements, other.m_elements);
232 std::swap(m_size, other.m_size);
233 std::swap(m_tss_used, other.m_tss_used);
246 template <
typename OtherAllocator>
249 for (
size_t i=0; i <
size(); ++i) m_elements[i] = other[i];
290 if (
size() != other.
size())
return false;
291 for (
size_t i=0;i<
size();++i)
if (*get_iter(i) != *other.get_iter(i))
return false;
302 if (
size() != other.
size())
return true;
303 for (
size_t i=0; i<
size(); ++i)
if (*get_iter(i) != *other.get_iter(i))
return true;
399 return (
double)
sizeof(T);
414 const Allocator & alloc=Allocator()
415 ): m_elements(0), m_size(0), m_tss_used(false), m_allocator(alloc)
419 m_elements(0), m_size(0), m_tss_used(false), m_allocator(bucket)
422 array(memory_bucket_ref bucket):
423 m_elements(0), m_size(0), m_tss_used(false), m_allocator(bucket) {}
430 array(size_type s=0,
const Allocator & alloc=
431 Allocator()): m_elements(0), m_size(0), m_tss_used(false),
432 m_allocator(alloc) {
resize(s);}
438 array(
const array & other): m_elements(0), m_size(other.m_size), m_tss_used(false), m_allocator(other.m_allocator) {
439 if (other.
size() == 0)
return;
440 alloc_copy(other.m_elements);
448 : m_elements(other.m_elements)
449 , m_size(other.m_size)
450 , m_tss_used(other.m_tss_used)
451 , m_allocator(other.m_allocator) {
452 other.m_elements =
nullptr;
454 other.m_tss_used =
false;
459 , m_size(view.
size())
462 if (view.
size() == 0)
return;
463 alloc_copy(&*view.
begin());
466 array(
const array_view_base<const T> & view)
468 , m_size(view.
size())
471 if (view.size() == 0)
return;
472 alloc_copy(&*view.begin());
491 if (
size != m_size) {
492 destruct_and_dealloc();
497 std::fill(m_elements+0, m_elements+m_size, elm);
505 std::swap(m_allocator, other.m_allocator);
506 std::swap(m_elements, other.m_elements);
507 std::swap(m_size, other.m_size);
508 std::swap(m_tss_used, other.m_tss_used);
521 destruct_and_dealloc();
531 size_type
size()
const {
return m_size;}
536 T *
get() {
return m_elements;}
541 const T *
get()
const {
return m_elements;}
566 void alloc_fill(
const T & elm) { bits::allocator_usage<T, Allocator>::alloc_fill(*
this, elm); }
573 void alloc_dfl() { bits::allocator_usage<T, Allocator>::alloc_dfl(*
this); }
580 void destruct_and_dealloc() { bits::allocator_usage<T, Allocator>::destruct_and_dealloc(*
this); }
586 Allocator m_allocator;
591 template <
typename T>
594 host.m_elements = host.m_size ?
reinterpret_cast<T*
>(tpie_new_array<trivial_same_size<T> >(host.m_size)) : 0;
595 host.m_tss_used =
true;
597 if (host.m_allocator.bucket)
598 host.m_allocator.bucket->count +=
sizeof(T) * host.m_size;
600 std::uninitialized_copy(copy_from+0, copy_from+host.m_size, host.m_elements+0);
604 host.m_elements = host.m_size ?
reinterpret_cast<T*
>(tpie_new_array<trivial_same_size<T> >(host.m_size)) : 0;
605 host.m_tss_used =
true;
607 if (host.m_allocator.bucket)
608 host.m_allocator.bucket->count +=
sizeof(T) * host.m_size;
611 std::uninitialized_fill(host.m_elements+0, host.m_elements+host.m_size, elm);
615 host.m_elements = host.m_size ? tpie_new_array<T>(host.m_size) : 0;
616 host.m_tss_used =
false;
618 if (host.m_allocator.bucket)
619 host.m_allocator.bucket->count +=
sizeof(T) * host.m_size;
623 if (host.m_allocator.bucket)
624 host.m_allocator.bucket->count -=
sizeof(T) * host.m_size;
626 if (!host.m_tss_used) {
633 for (
size_t i = 0; i < host.m_size; ++i) {
634 host.m_elements[i].~T();
640 template <
typename T,
typename Allocator>
643 host.m_elements = host.m_size ? host.m_allocator.allocate(host.m_size) : 0;
644 for (
size_t i = 0; i < host.m_size; ++i) {
645 host.m_allocator.construct(host.m_elements+i, copy_from[i]);
649 static void alloc_fill(array<T, Allocator> & host,
const T & elm) {
650 host.m_elements = host.m_size ? host.m_allocator.allocate(host.m_size) : 0;
651 for (
size_t i = 0; i < host.m_size; ++i) {
652 host.m_allocator.construct(host.m_elements+i, elm);
656 static void alloc_dfl(array<T, Allocator> & host) {
657 host.m_elements = host.m_size ? host.m_allocator.allocate(host.m_size) : 0;
658 for (
size_t i = 0; i < host.m_size; ++i) {
659 host.m_allocator.construct(host.m_elements+i);
663 static void destruct_and_dealloc(array<T, Allocator> & host) {
664 for (
size_t i = 0; i < host.m_size; ++i) {
665 host.m_allocator.destroy(host.m_elements+i);
667 host.m_allocator.deallocate(host.m_elements, host.m_size);
673 template <
typename T>
674 std::ostream & operator<<(std::ostream & o,
const array<T> & a) {
677 for(
size_t i=0; i < a.size(); ++i) {
678 if (first) first =
false;
708 template <
typename T>
716 template <
typename TT1,
bool forward1,
typename TT2,
bool forward2>
722 ptrdiff_t dist =
copy(&*first, &*last, &*d_first) - &*d_first;
723 return d_first + dist;
729 template <
typename TT,
bool forward,
typename OutputIterator>
733 OutputIterator d_first) {
735 return copy(&*first, &*last, d_first);
741 template <
typename TT,
bool forward,
typename InputIterator>
747 ptrdiff_t dist =
copy(first, last, &*d_first) - &*d_first;
748 return d_first + dist;
753 #endif //__TPIE_ARRAY_H__